Initial commit

This commit is contained in:
Evercatch
2026-02-18 15:30:22 +00:00
commit 958a1b3c12
13 changed files with 601 additions and 0 deletions

39
.env.example Normal file
View File

@@ -0,0 +1,39 @@
# ─────────────────────────────────────────────
# Evercatch — Environment Variables
# Copy this file to .env and fill in values.
# NEVER commit .env to version control.
# ─────────────────────────────────────────────
# App
APP_ENV=development
APP_PORT=8000
APP_SECRET_KEY=change-me
# Database — PostgreSQL
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=evercatch
POSTGRES_USER=evercatch
POSTGRES_PASSWORD=change-me
# Database — MongoDB
MONGO_URI=mongodb://localhost:27017
MONGO_DB=evercatch_events
# Redis
REDIS_URL=redis://localhost:6379
# Stripe
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
STRIPE_PRICE_ID_INDIE=price_...
STRIPE_PRICE_ID_PRO=price_...
STRIPE_PRICE_ID_BUSINESS=price_...
# Providers
SENDGRID_WEBHOOK_KEY=
SHOPIFY_WEBHOOK_SECRET=
GITHUB_WEBHOOK_SECRET=
# Internal
BOT_ACCESS_TOKEN=

View File

@@ -0,0 +1,44 @@
name: Bug Report
about: Report a bug specific to this repository (API, tests, CI, etc.)
labels:
- "type: bug"
body:
- type: markdown
attributes:
value: |
**Note:** For product-level bugs and feature requests, use [Evercatch Board](https://git.psmattas.com/Evercatch/evercatch-board/issues).
This template is for repo-specific issues (broken tests, CI failures, dependency problems, etc.).
- type: input
id: summary
attributes:
label: Summary
placeholder: Brief description of the bug
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce
value: |
1.
2.
3.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
validations:
required: true
- type: textarea
id: actual
attributes:
label: Actual Behavior
validations:
required: true
- type: textarea
id: context
attributes:
label: Additional Context
description: Logs, screenshots, environment details, etc.

View File

@@ -0,0 +1,35 @@
name: Documentation
about: Report missing, incorrect, or outdated documentation in this repo
labels:
- "type: docs"
body:
- type: markdown
attributes:
value: |
Use this for documentation issues within this repository (README, inline docs, API docs, setup guides).
For product-level documentation requests, use [Evercatch Board](https://git.psmattas.com/Evercatch/evercatch-board/issues).
- type: input
id: page
attributes:
label: Affected Page / File
placeholder: e.g. README.md, monitoring/README.md, app/api/v1/webhooks.py
validations:
required: true
- type: dropdown
id: type
attributes:
label: Type
options:
- Missing documentation
- Incorrect / outdated information
- Unclear or confusing
- Typo / formatting
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: What needs to change and why?
validations:
required: true

View File

@@ -0,0 +1,46 @@
name: Security Vulnerability
about: Report a security vulnerability in this repository
labels:
- "type: security"
- "priority: critical"
body:
- type: markdown
attributes:
value: |
**Please do not disclose sensitive details publicly.** If this is a critical vulnerability,
contact the maintainers directly before filing a public issue.
- type: input
id: summary
attributes:
label: Summary
placeholder: Brief description of the vulnerability
validations:
required: true
- type: dropdown
id: severity
attributes:
label: Severity
options:
- Critical — active exploit / data exposure
- High — exploitable with moderate effort
- Medium — limited impact or requires specific conditions
- Low — informational / hardening suggestion
validations:
required: true
- type: textarea
id: description
attributes:
label: Description
description: What is the vulnerability and how can it be exploited?
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Steps to Reproduce
description: Provide enough detail for someone to verify the issue.
- type: textarea
id: remediation
attributes:
label: Suggested Remediation
description: If you have a fix in mind, describe it here.

View File

@@ -0,0 +1,20 @@
### Ticket
<!-- Use cross-repo reference format. Leave blank for repo-only changes. -->
Resolves Evercatch/evercatch-board#
### Summary
<!-- One or two sentences — what and why. Details are in the ticket. -->
### Changes
-
-
### Checklist
- [ ] Self-reviewed
- [ ] Tests added/updated and passing
- [ ] Docs updated (if applicable)

View File

@@ -0,0 +1,88 @@
name: PR Management Bot
on:
pull_request:
types: [opened, edited, synchronize, reopened]
branches: [main]
jobs:
pr-bot:
runs-on: ubuntu-latest
env:
API_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
API_BASE_URL: https://git.psmattas.com/api/v1
REPO: ${{ gitea.repository }}
PR_NUMBER: ${{ gitea.event.pull_request.number }}
PR_AUTHOR: ${{ gitea.actor }}
steps:
# FIX 1: Use standard short syntax to avoid upstream gitea.com connection errors
- name: Check out repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Auto-label from commit messages
run: |
API_URL="$API_BASE_URL/repos/$REPO/pulls/$PR_NUMBER/commits"
MESSAGES=$(curl -s -H "Authorization: token $API_TOKEN" "$API_URL" | jq -r '.[].commit.message')
# Match "EC-NUM: TYPE" or standalone "TYPE:" at start of commit message
UNIQUE_TYPES=$(echo "$MESSAGES" | grep -oP '^(EC-\d+: )?\K(FEAT|FIX|DOCS|STYLE|REFACTOR|PERF|TEST|CHORE)(?=:)' | sort -u || true)
if [[ -z "$UNIQUE_TYPES" ]]; then
echo "No semantic commit types found."
exit 0
fi
LABELS_JSON=$(echo "$UNIQUE_TYPES" | jq -R '("type: " + (. | ascii_downcase))' | jq -s '{"labels": .}')
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER/labels"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABELS_JSON" "$ISSUES_API_URL"
- name: Auto-assign author
if: gitea.event.pull_request.assignees_count == 0 && gitea.actor != 'gitea-actions' && gitea.actor != 'EC-bot'
run: |
ISSUES_EDIT_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
JSON_PAYLOAD=$(echo "$PR_AUTHOR" | jq -R '{"assignees": [.]}')
curl -s -f -X PATCH -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$JSON_PAYLOAD" "$ISSUES_EDIT_API_URL"
- name: Add conflict label and comment
if: gitea.event.pull_request.merge_status == 'CONFLICT'
run: |
COMMENT_BODY="🚨 **Merge Conflict Detected** 🚨\n\nHi @$PR_AUTHOR, this pull request has merge conflicts with the \`main\` branch. Please resolve them by rebasing or merging \`main\` into your branch so the PR can be reviewed."
COMMENT_JSON=$(jq -n --arg body "$COMMENT_BODY" '{"body": $body}')
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER/comments"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$ISSUES_API_URL"
LABEL_JSON='{ "labels": ["status: needs-rebase"] }'
LABELS_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER/labels"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABEL_JSON" "$LABELS_API_URL"
- name: Remove 'needs-rebase' label if clean
if: gitea.event.pull_request.merge_status != 'CONFLICT'
run: |
LABEL_TO_REMOVE="status: needs-rebase"
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
CURRENT_LABELS_JSON=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels")
LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$LABEL_TO_REMOVE" '.[] | select(.name == $name) | .id')
if [ -n "$LABEL_ID" ]; then
echo "Found and removing '$LABEL_TO_REMOVE' (ID: $LABEL_ID)..."
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$LABEL_ID"
fi
- name: Auto-assign reviewers
run: |
target_reviewer="psmattas"
# FIX 3: Check if the author is the target reviewer to avoid API error (422)
if [[ "$PR_AUTHOR" == "$target_reviewer" ]]; then
echo "Author is $target_reviewer. Skipping self-review request."
exit 0
fi
REVIEWERS_JSON="{\"reviewers\": [\"$target_reviewer\"]}"
echo "Requesting review from: $target_reviewer"
API_URL="$API_BASE_URL/repos/$REPO/pulls/$PR_NUMBER/requested_reviewers"
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$REVIEWERS_JSON" "$API_URL"

View File

@@ -0,0 +1,110 @@
name: PR Title Checker
on:
pull_request:
types: [opened, edited, synchronize]
jobs:
enforce-pr-title:
name: Validate PR Title Format
runs-on: ubuntu-latest
steps:
- name: Check PR Title and Manage Labels/Comments
env:
API_TOKEN: ${{ secrets.BOT_ACCESS_TOKEN }}
API_BASE_URL: https://git.psmattas.com/api/v1
REPO: ${{ gitea.repository }}
PR_NUMBER: ${{ gitea.event.pull_request.number }}
PR_TITLE: ${{ gitea.event.pull_request.title }}
COMMENT_BODY_INVALID: |
Hi @${{ gitea.actor }}, thanks for the contribution!
The title of this pull request does not follow the required format. This PR is currently **blocked from merging**.
Please update the title to match one of these formats:
**Board issue:** `EC-[NUMBER]: [TYPE]: Description`
**Repo-only:** `[TYPE]: Description`
- **Valid types:** `FEAT`, `FIX`, `DOCS`, `REFACTOR`, `STYLE`, `PERF`, `TEST`, `CHORE`
- **Examples:**
- `EC-10: FEAT: Add monitoring stack`
- `FIX: Correct typo in health endpoint`
PRs with an `EC-` prefix automatically reference `Evercatch/evercatch-board#`.
<!-- PR_TITLE_VALIDATOR_COMMENT -->
COMMENT_BODY_WIP: |
Hi @${{ gitea.actor }}, this pull request has been marked as a **Work in Progress**.
While in this state, it is **blocked from merging**.
When the PR is ready for review, please remove the `WIP:` prefix from the title. This check will re-run automatically and remove the blocking label.
<!-- WIP_VALIDATOR_COMMENT -->
run: |
WIP_LABEL="status: work-in-progress"
INVALID_LABEL="status: invalid-title"
WIP_REGEX="^WIP:"
# Accept either "EC-NUM: TYPE: desc" or "TYPE: desc"
FORMAT_REGEX="^(EC-[0-9]+: )?(FEAT|FIX|DOCS|REFACTOR|STYLE|PERF|TEST|CHORE): .+$"
ISSUES_API_URL="$API_BASE_URL/repos/$REPO/issues/$PR_NUMBER"
if [ -z "$PR_NUMBER" ]; then
echo "::error::Could not determine PR Number. Aborting."
exit 1
fi
if [[ "$PR_TITLE" =~ $WIP_REGEX ]]; then
echo " PR is marked as a Work in Progress."
LABEL_JSON=$(echo "$WIP_LABEL" | jq -R '{"labels": [.]}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABEL_JSON" "$ISSUES_API_URL/labels"
WIP_COMMENT_IDENTIFIER="<!-- WIP_VALIDATOR_COMMENT -->"
EXISTING_COMMENTS=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/comments")
if ! echo "$EXISTING_COMMENTS" | grep -q "$WIP_COMMENT_IDENTIFIER"; then
echo "Posting WIP comment."
COMMENT_JSON=$(jq -n --arg body "$COMMENT_BODY_WIP" '{"body": $body}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$ISSUES_API_URL/comments"
fi
exit 1
elif [[ "$PR_TITLE" =~ $FORMAT_REGEX ]]; then
echo "✅ PR title format is correct and not a WIP."
echo "Checking for labels to remove..."
CURRENT_LABELS_JSON=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels")
INVALID_LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$INVALID_LABEL" '.[] | select(.name == $name) | .id')
if [ -n "$INVALID_LABEL_ID" ]; then
echo "Found and removing '$INVALID_LABEL' (ID: $INVALID_LABEL_ID)..."
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$INVALID_LABEL_ID"
fi
WIP_LABEL_ID=$(echo "$CURRENT_LABELS_JSON" | jq --arg name "$WIP_LABEL" '.[] | select(.name == $name) | .id')
if [ -n "$WIP_LABEL_ID" ]; then
echo "Found and removing '$WIP_LABEL' (ID: $WIP_LABEL_ID)..."
curl -s -f -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$WIP_LABEL_ID"
fi
exit 0
else
echo "❌ ERROR: PR title does not match the required format."
echo "Adding '$INVALID_LABEL' label..."
LABEL_JSON=$(echo "$INVALID_LABEL" | jq -R '{"labels": [.]}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$LABEL_JSON" "$ISSUES_API_URL/labels"
# Remove WIP label just in case
ENCODED_WIP_LABEL=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$WIP_LABEL'))")
curl -s -X DELETE -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/labels/$ENCODED_WIP_LABEL" || true
INVALID_COMMENT_IDENTIFIER="<!-- PR_TITLE_VALIDATOR_COMMENT -->"
EXISTING_COMMENTS=$(curl -s -H "Authorization: token $API_TOKEN" "$ISSUES_API_URL/comments")
if ! echo "$EXISTING_COMMENTS" | grep -q "$INVALID_COMMENT_IDENTIFIER"; then
echo "Posting invalid title comment."
COMMENT_JSON=$(jq -n --arg body "$COMMENT_BODY_INVALID" '{"body": $body}')
curl -s -f -X POST -H "Authorization: token $API_TOKEN" -H "Content-Type: application/json" -d "$COMMENT_JSON" "$ISSUES_API_URL/comments"
fi
exit 1
fi

47
.gitignore vendored Normal file
View File

@@ -0,0 +1,47 @@
# Environment
.env
.env.*
!.env.example
# Python
__pycache__/
*.py[cod]
*.pyo
*.pyd
.Python
*.egg-info/
dist/
build/
.venv/
venv/
*.log
# Node / Angular
node_modules/
dist/
.angular/
*.tsbuildinfo
# Docker
.docker/
# IDE
.vscode/
.idea/
*.swp
*.swo
.DS_Store
Thumbs.db
# Coverage
.coverage
htmlcov/
coverage/
*.lcov
# Secrets
*.pem
*.key
*.p12
*.pfx
secrets/

5
CODEOWNERS Normal file
View File

@@ -0,0 +1,5 @@
# Evercatch Code Owners
# These users are automatically requested for review on PRs.
# Format: path @username
* @psmattas

63
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,63 @@
# Contributing to Evercatch
Thank you for contributing. Please read this guide before opening issues or PRs.
---
## 🌿 Branching
Branch from `main` using the format `EC-ID-short-description`.
```bash
git checkout -b EC-12-implement-stripe-inbound
```
---
## ✨ Commit Messages
Follow the Conventional Commits standard prefixed with the issue ID.
**Format:** `EC-00: <type>(scope): message`
| Type | Description |
| :--- | :--- |
| `feat` | New feature |
| `fix` | Bug fix |
| `docs` | Documentation |
| `style` | Formatting |
| `refactor` | Refactor |
| `perf` | Performance |
| `test` | Tests |
| `build` | Build system |
| `ci` | CI/CD config |
| `chore` | Maintenance |
**Examples:**
- `EC-12: feat(webhooks): implement stripe inbound endpoint`
- `EC-18: fix(relay): resolve double-delivery on retry`
---
## 🔍 Pull Requests
- Link the issue in your PR description
- All CI checks must pass before requesting review
- Minimum one approval required to merge
- Keep PRs focused — one feature or fix per PR
---
## 🏷️ Labels
Apply the appropriate labels to your issue or PR:
- `type:` — what kind of change is this
- `priority:` — how urgent is it
- `status:` — current state of the issue or PR
---
## ❓ Questions
Open an issue with the `type: chore` label or reach out via the org README.

8
LICENSE Normal file
View File

@@ -0,0 +1,8 @@
Copyright (c) 2026 Evercatch. All rights reserved.
This software and its source code are proprietary and confidential.
Unauthorised copying, distribution, modification, or use of this software,
in whole or in part, via any medium, is strictly prohibited without the
prior written permission of Evercatch.
For licensing enquiries, contact: legal@evercatch.io

72
README.md Normal file
View File

@@ -0,0 +1,72 @@
# 📦 Repository Name
> Short one-line description of what this repository does.
---
## 🧭 Overview
Describe what this service/module is responsible for within the Evercatch platform.
---
## 🛠️ Tech Stack
| Layer | Technology |
| :--- | :--- |
| Language | — |
| Framework | — |
| Key Dependencies | — |
---
## 🚀 Getting Started
### Prerequisites
- Docker & Docker Compose
- Node.js / Python (specify version)
### Local Development
```bash
# Clone the repo
git clone https://git.psmattas.com/Evercatch/REPO_NAME.git
cd REPO_NAME
# Copy environment variables
cp .env.example .env
# Start services
docker compose up -d
```
---
## 🌿 Branching & Commits
All work follows the Evercatch contribution guide defined in the org README.
**Branch format:** `EC-ID-short-description`
**Commit format:** `EC-00: type(scope): message`
See [Evercatch Org README](https://git.psmattas.com/Evercatch) for full conventions.
---
## ⚙️ CI/CD
Automated via Jenkins. Merges to `main` trigger staging deployments.
| Pipeline | Status |
| :--- | :---: |
| Build | ![Build Status](https://img.shields.io/badge/build-pending-lightgrey) |
| Lint | ![Lint Status](https://img.shields.io/badge/lint-pending-lightgrey) |
| Test | ![Test Status](https://img.shields.io/badge/tests-pending-lightgrey) |
---
## 📄 License
**Copyright © 2026 Evercatch.**
Proprietary and confidential. Unauthorised distribution is strictly prohibited.

24
SECURITY.md Normal file
View File

@@ -0,0 +1,24 @@
# Security Policy
## Reporting a Vulnerability
If you discover a security vulnerability in any Evercatch repository,
please do **not** open a public issue.
Report it privately to: **security@evercatch.io**
Include:
- A description of the vulnerability
- Steps to reproduce
- Potential impact
- Any suggested fixes if available
We will acknowledge receipt within 48 hours and aim to release a fix
within 14 days depending on severity.
## Supported Versions
| Version | Supported |
| :--- | :---: |
| Latest `main` | ✅ |
| Older releases | ❌ |