S02 — Application core: config, main.ts and error handling
| Field |
Value |
| ID |
S02 |
| ETA |
1 — Foundation and database |
| Priority |
P0 |
| Complexity |
Medium |
| Depends on |
S01 |
| Atomic tasks |
SRV-004, SRV-005, SRV-006 |
| Milestone |
Server boots with validated config and uniform errors |
Executive summary
This deliverable consolidates 3 atomic server tasks into one sprint-sized ticket for Application core: config, main.ts and error handling.
Success means: Server boots with validated config and uniform errors.
Product context
Ding Payments is a self-custodial Stellar P2P app: the server validates NFC payment requests, enforces hybrid Supabase + WebAuthn authorization, relays signed XDR to Horizon, and indexes history.
User stories
- As a developer, I want S02 complete so I can run the next ETA without manual archaeology.
- As a receiver, I want my NFC payment request validated consistently with the canonical contract.
- As a sender, I want clear API errors when a payment request is malformed or expired.
- As an operator, I want migrations, health checks, and logs sufficient to debug testnet payments.
Prerequisites
- Deliverable S01 merged and deployed to dev
- Node 20+, npm, Supabase project credentials, Postgres reachable via
DATABASE_URL
- Read Sections 3–6 of server-build-plan.md before coding
Atomic sub-task checklist
| SRV-ID |
Title |
Key deliverable |
| SRV-004 |
Configure ConfigModule and env validation |
Configure ConfigModule and env validation |
| SRV-005 |
Bootstrap production-ready main.ts |
Bootstrap production-ready main.ts |
| SRV-006 |
Global exception filter and error format |
Global exception filter and error format |
Scope — In
- All atomic tasks SRV-004, SRV-005, SRV-006 as specified in server-build-plan.md
- NestJS 11 patterns: modules, providers, DTOs with class-validator, Swagger decorators where applicable
- Unit and/or E2E tests for new behavior; keep CI green (
ci-server.yml)
- Production-quality code under
ding-server/src/ for S02
Scope — Out
- Client UI or Expo changes (ding-payments repo)
- Mainnet launch configuration (testnet MVP only unless explicitly toggled)
- Push notifications on payment confirmation (post-MVP P3)
- Custodial wallets or server-side key storage
- Features not listed in atomic SRV IDs for this deliverable
Architecture & conventions
Target architecture from server-build-plan.md Section 3: flat src/modules/* layout, ConfigModule validation, global exception filter, URI versioning /v1.
ding-server/
├── src/
│ ├── main.ts
│ ├── app.module.ts
│ ├── config/
│ ├── common/filters/
│ ├── database/
│ ├── auth/
│ ├── supabase/
│ ├── stellar/
│ ├── webauthn/
│ ├── contracts/
│ └── modules/
│ ├── users/
│ ├── payment-requests/
│ ├── payments/
│ └── transactions/
├── prisma/schema.prisma
├── docs/
└── test/
Environment variables (full .env.example block):
# App
NODE_ENV=development
PORT=3000
API_PREFIX=v1
CORS_ORIGINS=http://localhost:8081,exp://localhost:8081
# Database (Supabase PostgreSQL)
DATABASE_URL=postgresql://postgres:PASSWORD@PROJECT.pooler.supabase.com:6543/postgres?pgbouncer=true
DIRECT_URL=postgresql://postgres:PASSWORD@PROJECT.supabase.com:5432/postgres
# Supabase Auth
SUPABASE_URL=https://PROJECT.supabase.co
SUPABASE_JWT_SECRET=your-jwt-secret
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
# Stellar
STELLAR_NETWORK=testnet
STELLAR_HORIZON_URL=https://horizon-testnet.stellar.org
STELLAR_RPC_URL=https://soroban-testnet.stellar.org
STELLAR_USDC_ISSUER=GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5
STELLAR_NETWORK_PASSPHRASE=Test SDF Network ; September 2015
# WebAuthn
WEBAUTHN_RP_ID=localhost
WEBAUTHN_RP_NAME=Ding Payments
WEBAUTHN_ORIGIN=http://localhost:8081
# Payments
PAYMENT_SUBMIT_TIMEOUT_MS=300000
PAYMENT_POLL_INTERVAL_MS=2000
PAYMENT_POLL_MAX_ATTEMPTS=30
# Rate limiting
THROTTLE_TTL_MS=60000
THROTTLE_LIMIT=100
Files to create/modify
ding-server/src/
See server-build-plan.md atomic files for SRV-004
See server-build-plan.md atomic files for SRV-005
See server-build-plan.md atomic files for SRV-006
Implementation guide
- Implement SRV-004 — Configure ConfigModule and env validation; cross-check Section 8 in server-build-plan.md for files and snippets.
- Implement SRV-005 — Bootstrap production-ready main.ts; cross-check Section 8 in server-build-plan.md for files and snippets.
- Implement SRV-006 — Global exception filter and error format; cross-check Section 8 in server-build-plan.md for files and snippets.
- Run
npm run lint and fix any new violations.
- Run targeted unit tests for the module(s) touched.
- Run
npm run test:e2e when HTTP surface changed.
- Update Swagger decorators if routes or DTOs changed.
- Verify error responses use
{ statusCode, message, code?, errors? } shape from Section 5.
- Document any new env vars in
.env.example and README.
- Manual smoke test with
npm run start:dev and curl/httpie against /v1 routes.
Acceptance criteria
Test plan
- Unit: Services, validators, and state machine pure functions for S02
- Integration: Prisma against local Postgres or test container for repositories
- E2E: Supertest against Nest app with JWT mock and Stellar SDK mocks
- Contract: payment-request.v1 golden vectors (S08+) — invalid BTC/ETH assets rejected
- Manual: curl examples from Section 5 and Appendices
- Regression: Re-run auth suite when touching guards (S06/S07)
- Performance: Smoke load on validate when approaching S20
Client coordination
Client EXPO_PUBLIC_API_URL must target this server's /v1 prefix once C16 starts.
Security notes
- Never log
SUPABASE_JWT_SECRET, SUPABASE_SERVICE_ROLE_KEY, or raw WebAuthn challenges
- Validate all inbound DTOs; reject unknown fields where strict mode applies
- Use parameterized Prisma queries only — no raw SQL unless documented
- Follow hybrid auth model: Supabase session + WebAuthn for payment approval
Risks & pitfalls
- Scope creep — stay within listed SRV atomic tasks for this sprint
- Drift from client NFC contract — coordinate before changing validation rules
- Stellar testnet instability — use health checks and retries (S12/S13)
- Prisma migration conflicts — serialize DB changes with team
- WebAuthn environment mismatch between dev client and server origins
- Underestimating E2E flakiness — mock Horizon in tests where possible
Definition of done
Source: build plan
S02 — Application core: config, main.ts and error handling
Executive summary
This deliverable consolidates 3 atomic server tasks into one sprint-sized ticket for Application core: config, main.ts and error handling.
Success means: Server boots with validated config and uniform errors.
Product context
Ding Payments is a self-custodial Stellar P2P app: the server validates NFC payment requests, enforces hybrid Supabase + WebAuthn authorization, relays signed XDR to Horizon, and indexes history.
User stories
Prerequisites
DATABASE_URLAtomic sub-task checklist
Scope — In
ci-server.yml)ding-server/src/for S02Scope — Out
Architecture & conventions
Target architecture from server-build-plan.md Section 3: flat
src/modules/*layout, ConfigModule validation, global exception filter, URI versioning/v1.Environment variables (full
.env.exampleblock):Files to create/modify
ding-server/src/See server-build-plan.md atomic files for SRV-004See server-build-plan.md atomic files for SRV-005See server-build-plan.md atomic files for SRV-006Implementation guide
npm run lintand fix any new violations.npm run test:e2ewhen HTTP surface changed.{ statusCode, message, code?, errors? }shape from Section 5..env.exampleand README.npm run start:devand curl/httpie against/v1routes.Acceptance criteria
.envgitignorednpm run prisma:generate)Test plan
Client coordination
Client
EXPO_PUBLIC_API_URLmust target this server's/v1prefix once C16 starts.Security notes
SUPABASE_JWT_SECRET,SUPABASE_SERVICE_ROLE_KEY, or raw WebAuthn challengesRisks & pitfalls
Definition of done
Source: build plan