SPF record management application
  • Python 64.2%
  • TypeScript 34.7%
  • CSS 0.5%
  • JavaScript 0.5%
Find a file
Hermes Agent 4bd28d43f2
Some checks failed
CI / pytest (push) Has been cancelled
CI / frontend-checks (push) Has been cancelled
CI / e2e (push) Has been cancelled
fix(deploy): add curl to Docker images for Coolify healthchecks
Coolify's healthcheck uses curl or wget to reach the health endpoint.
Both images were missing these tools, causing the apps to fail healthchecks
and show as exited:unhealthy.

- Dockerfile.api: added curl to apt-get install line alongside libpq5
- Dockerfile.web: added curl install in the runtime stage

Fixes: spfpletter-api and spfpletter-web exited:unhealthy on Coolify
2026-09-03 06:12:31 +00:00
.github fix(ci): revert eslint to 9.x + ignore eslint majors (eslint 10 breaks eslint-plugin-react) (#57) 2026-08-20 00:05:41 +02:00
.vscode revert header cheeseburger menu and add components 2025-03-31 15:06:02 +00:00
alembic feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
api feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
app feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
components feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
config run prettier 2025-03-29 00:25:53 +00:00
deploy fix(deploy): add curl to Docker images for Coolify healthchecks 2026-09-03 06:12:31 +00:00
docs feat(email-auth): DMARC + DKIM checks (E4) 2026-08-09 18:57:40 +00:00
e2e fix(ci): resolve CI failures on security-hardening branch 2026-08-08 18:01:46 +00:00
lib refactor(frontend): extract shared copyToClipboard helper 2026-08-09 11:45:51 +00:00
public working theme toggle, all colors corrected 2025-03-27 19:58:47 +00:00
tests feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
.dockerignore feat(ops): app deploy manifests + backup/restore runbook (H5) 2026-08-08 23:59:00 +00:00
.env.local.example feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
.gitignore feat(ci): full CI gates — tsc, eslint, pyright, build, Vitest, Playwright smoke (I2) 2026-08-08 17:39:08 +00:00
.npmrc Modernize stack: upgrade deps, migrate configs, remove Vercel 2026-06-06 11:52:20 +00:00
alembic.ini Add managed SPF chaining and Alembic baseline 2026-06-07 21:19:16 +00:00
components.json Initial commit 2025-03-23 21:59:54 +00:00
compose.yml feat(ops): app deploy manifests + backup/restore runbook (H5) 2026-08-08 23:59:00 +00:00
eslint.config.mjs chore(lint): stop ESLint from scanning .venv and build output 2026-06-11 15:19:51 +00:00
next.config.js feat(ops): app deploy manifests + backup/restore runbook (H5) 2026-08-08 23:59:00 +00:00
package-lock.json Merge pull request #55 from devmorkon/dependabot/npm_and_yarn/typescript-eslint/eslint-plugin-8.67.0 2026-08-24 21:26:18 +02:00
package.json Merge pull request #56 from devmorkon/dependabot/npm_and_yarn/sonner-2.0.8 2026-08-24 21:26:15 +02:00
playwright.config.ts ci: fix e2e slowness/hangs (timeout + cache + healthchecks) (#53) 2026-08-19 23:54:30 +02:00
postcss.config.js Modernize stack: upgrade deps, migrate configs, remove Vercel 2026-06-06 11:52:20 +00:00
pyrightconfig.json fix(types): type primary keys as int and keep reportArgumentType strict 2026-06-14 07:44:10 +00:00
pytest.ini test: org/auth pytest suite and CI workflow 2026-06-06 15:56:04 +00:00
README.md feat(docs): add quickstart and documentation sections to README; include .env.local.example 2026-07-04 09:54:56 +00:00
requirements.txt feat(billing): Stripe checkout + webhook, tier sync, /plans page (E1) 2026-08-10 15:53:15 +00:00
tsconfig.json Modernize stack: upgrade deps, migrate configs, remove Vercel 2026-06-06 11:52:20 +00:00
vitest.config.ts feat(ci): full CI gates — tsc, eslint, pyright, build, Vitest, Playwright smoke (I2) 2026-08-08 17:39:08 +00:00
vitest.setup.ts feat(ci): full CI gates — tsc, eslint, pyright, build, Vitest, Playwright smoke (I2) 2026-08-08 17:39:08 +00:00

SPF Pletter

SPF flattening and managed (hosted) SPF records. Flattens a domain's SPF to stay under the 10-DNS-lookup limit, and can host the flattened record as a managed TXT record (customers point an include: or redirect= at our zone), kept current by an auto-refresh loop with snapshot history, revert, and webhook notifications.

Stack

  • Frontend — Next.js 16 (App Router) + React 19 + Tailwind 4, in app/ and components/.
  • Backend — FastAPI + SQLModel + Alembic, in api/. DNS via dnspython; hosted records published through the PowerDNS HTTP API.
  • DB — SQLite for dev (auto-created), Postgres for production (Alembic-managed; see docs/migrations.md).

Quickstart

Requires Node 20+, Python 3.11+, and uv.

npm install
cp .env.local.example .env.local   # fill in secrets; see docs/operations.md
npm run dev                        # Next.js :3000 + FastAPI :8000

Then open http://localhost:3000 (try /preview for the anonymous flatten flow) or the API docs at http://127.0.0.1:8000/api/py/docs.

Tests & checks

uv run python -m pytest -q   # backend suite
npx tsc --noEmit             # TS typecheck
npx eslint .                 # lint

Documentation

Doc Contents
CLAUDE.md Architecture map, conventions, and gotchas (written for AI agents, useful for humans too)
docs/operations.md Hosted-DNS env vars, auto-refresh, failure behavior
docs/migrations.md Schema/deploy discipline, revision runbook
docs/webhooks.md Webhook payload contract
docs/dns-hardening.md PowerDNS API lockdown architecture
docs/incident-checklist.md DNS publishing incident runbook
deploy/ Ready-to-apply PowerDNS/nginx hardening configs