Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .env-dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# GENERAL
PROJECT_NAME=ideologicalatlas
RESEND_API_KEY=CHANGE-ME
API_KEY=CHANGE-ME
PORT=5051
LOG_LEVEL=INFO
ENVIRONMENT=local

# EMAIL
FROM_EMAIL=noreply@notifications.ideologicalatlas.com
FROM_EMAIL_NAME=Ideological Atlas
BASE_SITE_URL=localhost:4045

# TESTING
TEST_EMAIL=CHANGE-ME
TEST_LANGUAGE=es
TEST_TEMPLATE=register
TEST_CONTEXT={"user_uuid": "test-uuid-123", "name": "Test User"}
25 changes: 25 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
name: 🐛 Bug Report
about: Create a report to help us improve
title: "[FIX] "
labels: bug
assignees: ''
---

## Bug Description
A clear and concise description of the issue.

## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. See error

## Expected Behavior
What should have happened instead.

## Environment
- OS: [e.g. Ubuntu 24]
- Browser/Version: [e.g. Chrome 90]

## Screenshots or Logs
(If applicable, paste logs or images here)
16 changes: 16 additions & 0 deletions .github/ISSUE_TEMPLATE/chore.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: 🧹 Chore
about: Technical tasks, cleanup, refactoring, or dependencies
title: "[CHORE] "
labels: chore
assignees: ''
---

## Task
Technical description of the task (lib update, refactoring, CI cleanup, etc.).

## Reason
Why is this technical change necessary? (Tech debt, security, performance).

## Implementation Notes
Specific details for the developer.
21 changes: 21 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
name: 🚀 Feature Request
about: Suggest a new feature or improvement
title: "[FEAT] "
labels: enhancement
assignees: ''
---

## Description
A concise description of the requested feature.

## Motivation
What problem does it solve or what value does it bring?

## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
- [ ] Criterion 3

## Mockups or Screenshots
(If applicable, add images here)
10 changes: 10 additions & 0 deletions .github/issue-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
branchName: '${issue.number}-${issue.title}'
branches:
- label: bug
prefix: fix/
- label: enhancement
prefix: feature/
- label: chore
prefix: chore/
- label: '*'
prefix: other/
23 changes: 23 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Type of Change
- [ ] 🚀 New feature (non-breaking change which adds functionality)
- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
- [ ] 🧹 Chore (technical task, refactoring, maintenance)

## Description
Briefly describe the changes made in this Pull Request. Explain the solution and the reasoning.

## Related Issue
Closes # (Link the issue here, e.g., #123)

## How Has This Been Tested?
Please describe the tests that you ran to verify your changes.
- [ ] Unit Tests
- [ ] Manual Testing

## Checklist
- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes

## Screenshots (if applicable)
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI Pipeline

on:
push:

jobs:
quality-assurance:
name: Quality & Tests
runs-on: ubuntu-latest

steps:
- name: Checkout Code
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
version: "latest"

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.14"

- name: Install Dependencies
run: |
cd src
uv sync --extra dev

- name: Cache Pre-commit hooks
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
restore-keys: |
pre-commit-${{ runner.os }}-

- name: Run Pre-commit (Linting & Static Analysis)
run: |
cd src
uv run pre-commit run --all-files --config ../.pre-commit-config.yaml

- name: Run Tests with Coverage
env:
RESEND_API_KEY: "test_resend_key"
API_KEY: "test_api_key"
FROM_EMAIL: "test@example.com"
FROM_EMAIL_NAME: "Test User"
BASE_SITE_URL: "http://localhost:8000"
run: |
cd src
uv run coverage run -m unittest discover -s tests -t . -p "test_*.py"
uv run coverage xml

- name: Upload results to Codecov
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: Ideological-Atlas/notifications
files: ./src/coverage.xml
fail_ci_if_error: true
verbose: true
13 changes: 13 additions & 0 deletions .github/workflows/create-branch.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Create Issue Branch
on:
issues:
types: [assigned]

jobs:
create_branch:
runs-on: ubuntu-latest
steps:
- name: Create Issue Branch
uses: robvanderleek/create-issue-branch-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8 changes: 4 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/

# Abstra
# Abstra is an AI-powered process automation framework.
Expand All @@ -182,11 +182,11 @@ cython_debug/
.abstra/

# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
.vscode/

# Ruff stuff:
.ruff_cache/
Expand Down
72 changes: 72 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
repos:
- repo: https://github.com/pycqa/isort
rev: 7.0.0
hooks:
- id: isort
args: ["--profile", "black"]
exclude: '(^|/)(__init__\.py)$'

- repo: https://github.com/psf/black
rev: 25.12.0
hooks:
- id: black

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.14.10'
hooks:
- id: ruff
args: [ --exit-non-zero-on-fix ]
exclude: '(^|.*/)__init__\.py$'

- repo: https://github.com/asottile/pyupgrade
rev: v3.21.2
hooks:
- id: pyupgrade

- repo: https://github.com/shellcheck-py/shellcheck-py
rev: v0.11.0.1
hooks:
- id: shellcheck

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: check-yaml
- id: check-merge-conflict
- id: check-json
- id: name-tests-test
args:
- --pytest-test-first
exclude: '.*helpers.*'
- id: pretty-format-json
args:
- --autofix
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.19.1
hooks:
- id: mypy
args:
- --check-untyped-defs
- --ignore-missing-imports
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-use-type-annotations
- id: python-no-eval
- id: python-no-log-warn
- id: text-unicode-replacement-char
- repo: https://github.com/PyCQA/bandit
rev: 1.9.2
hooks:
- id: bandit
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
exclude: ^src/app/locales
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.0
hooks:
- id: gitleaks
83 changes: 83 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
ifneq ("$(wildcard .env)","")
include .env
export
endif

# --- Configuration ---
COMPOSE = docker compose
NOTIFICATIONS_SVC = $(PROJECT_NAME)_notifications
EXEC = docker exec -it $(NOTIFICATIONS_SVC)
TAIL_LOGS = 50

.DEFAULT_GOAL := up-logs

# --- System ---
.PHONY: help prepare-env clean-images remove-containers

help: ## Show this help message
@awk 'BEGIN {FS = ":.*## "} /^[a-zA-Z_-]+:.*## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)

prepare-env: ## Create .env from template
@test -f .env || cp .env-dist .env

clean-images: ## Remove all project images
@if [ -n "$(shell docker images -qa)" ]; then docker rmi $(shell docker images -qa) --force; fi

remove-containers: ## Remove all project containers
@if [ -n "$(shell docker ps -qa)" ]; then docker rm $(shell docker ps -qa); fi

# --- Docker Orchestration ---
up-logs: up logs

up: prepare-env ## Start containers in background
@$(COMPOSE) up --force-recreate -d --remove-orphans

down: ## Stop and remove containers
@$(COMPOSE) down

restart: ## Restart containers
@$(COMPOSE) restart

build: prepare-env ## Build images
@$(COMPOSE) build

down-up: down up-logs ## Recreate services

complete-build: build down-up ## Full rebuild cycle

# --- Development & Logs ---
.PHONY: logs all-logs bash shell lint format

logs: ## Show notifications service logs
@docker logs --tail $(TAIL_LOGS) -f $(NOTIFICATIONS_SVC)

bash: ## Access container bash
@$(EXEC) bash

shell: ## Access IPython shell
@$(EXEC) ipython


# --- Testing ---
.PHONY: trigger-test test install-dev-dependencies

install-dev-dependencies: ## Install dev dependencies
@$(EXEC) uv sync --extra dev

clean-coverage: ## Clean previous coverage results
@$(EXEC) rm -f .coverage coverage.xml

test: clean-coverage install-dev-dependencies ## Run tests with standard unittest
@$(EXEC) uv run coverage run -m unittest discover -s tests -t . -p "test_*.py"
@$(EXEC) uv run coverage xml
@$(EXEC) uv run coverage report

trigger-test: ## Send a test email via Curl using .env variables
@echo "Sending test email to $(TEST_EMAIL)..."
@echo "Template: $(TEST_TEMPLATE)"
@echo "Language: $(TEST_LANGUAGE)"
@curl -X POST http://localhost:$(PORT)/notifications/send \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $(API_KEY)" \
-d '{"to_email": "$(TEST_EMAIL)", "template_name": "$(TEST_TEMPLATE)", "language": "$(TEST_LANGUAGE)", "context": $(TEST_CONTEXT)}'
@echo "\nDone."
Loading