Initial commit

This commit is contained in:
Evercatch
2026-02-13 15:15:20 +00:00
commit 27c69d201f
10 changed files with 507 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,68 @@
### 🎟️ Evercatch Ticket
<!-- Required. Link to the Jira ticket. Use 'Resolves' to auto-close. -->
Resolves: [EC-XXX](<PROVIDE-LINK>)
### 🎯 Purpose & Impact
> Please provide a clear, high-level summary of the change and its intended impact. Why is this change valuable to the Evercatch platform?
### 🛠️ Key Changes
<!--
Please provide a bullet-point list of the technical changes you made.
This is the most important section for the reviewer.
-->
-
-
-
### 📸 Screenshots or Videos
<!-- If this PR includes UI changes, please provide a screenshot or a short video. This is the fastest way to get visual changes approved. -->
---
### ✅ Author's Definition of Done
<!-- Please check the boxes that apply. This is your declaration that the work is ready for review. -->
- [ ] I have performed a self-review of my own code.
- [ ] My code follows the style guidelines and architectural patterns of this project.
- [ ] I have added or updated tests that prove my feature works or my fix is effective.
- [ ] All new and existing tests pass locally with my changes.
- [ ] I have made corresponding changes to the documentation (if applicable).
<br>
<details>
<summary><strong>🔬 Reviewer's Guide & Additional Info (Click to Expand)</strong></summary>
---
#### Where should the reviewer start?
<!-- Optional: Give the reviewer a hint! e.g., "Start with `src/services/NewService.ts` as that contains the core logic." -->
#### 🏷️ Type of Change
<!-- This provides context for the change. Please check one. -->
- [ ] **FEAT**: A new feature
- [ ] **FIX**: A bug fix
- [ ] **DOCS**: Documentation only changes
- [ ] **STYLE**: Code style changes (formatting, etc.)
- [ ] **REFACTOR**: A code change that neither fixes a bug nor adds a feature
- [ ] **PERF**: A code change that improves performance
- [ ] **TEST**: Adding missing tests or correcting existing tests
- [ ] **CHORE**: Changes to the build process or auxiliary tools
---
</details>
---
![Evercatch Banner](https://placehold.co/1200x300/080c12/00e5ff?text=Evercatch&font=montserrat)

View File

@@ -0,0 +1,76 @@
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:
- name: Check out repository
uses: https://gitea.com/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')
UNIQUE_TYPES=$(echo "$MESSAGES" | grep -oP '^EC-\d+: \K(FEAT|FIX|DOCS|STYLE|REFACTOR|PERF|TEST|CHORE)' | sort -u)
if [[ -z "$UNIQUE_TYPES" ]]; then 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')
# Only try to delete the label if we found its 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: |
REVIEWERS_JSON='{ "reviewers": ["psmattas"] }'
if [[ -n "$REVIEWERS_JSON" ]]; then
echo "Requesting review from: $REVIEWERS_JSON"
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"
fi

View File

@@ -0,0 +1,105 @@
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**.
To fix this, please update the title to match the following structure:
**`EC-[JIRA_NUMBER]: [TYPE]: [Your Description]`**
- **Valid [TYPE] values are:** `FEAT`, `FIX`, `DOCS`, `REFACTOR`, `STYLE`, `PERF`, `TEST`, `CHORE`
- **Example:** `EC-42: FEAT: Add new user login endpoint`
Once you have updated the title, this check will re-run automatically and remove the blocking label.
<!-- 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="INVALID-TITLE-DO-NOT-MERGE"
WIP_REGEX="^WIP:"
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 | ❌ |