Every algorithm in docs/RULES.md, implemented exactly as written: the RUC check digit, the calendario perpetuo with weekend and holiday roll forward, CDC and KUDE QR parsing, keyword classification, computeF120, computeF515 and the dashboard projections, plus the two form definitions. Both worked examples reproduce verbatim on the first implementation: F120 at Gs. 277.273 to pay with the Gs. 350.000 flip case, F515 at Gs. 11.290.000 on a 5,65% effective rate. 162 tests over the package, coverage enforced at 100% statements, branches, functions and lines; the only exclusions are three bounded-loop guards marked v8 ignore with a comment saying why. No tax rule was invented. All six TODO-TAX-VERIFY items from RULES.md have a test pinning today's behaviour and a row in the DECISIONS.md register, so verification later is a red/green diff. Where RULES.md was silent the choice is marked SPEC-GAP in the code and listed too, the notable one being that taxpayer.hasIrp gates the deduction amount. No floats anywhere in a money path: money is a branded Pyg of whole guaranies and percentages go through integer arithmetic rounded half up. Also: contracts now takes IRP_CATEGORIES from rules rather than declaring the eight strings twice; classification returns reason codes with catalog strings in both locales, so the detail sheet localizes; apps/api/.env.example now names the same web port as apps/web/.env.example, without which a fresh checkout fails sign in on the origin check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
64 lines
2.4 KiB
Bash
64 lines
2.4 KiB
Bash
# apps/api environment. Copy to .env and adjust. Every variable is validated at boot
|
|
# by src/lib/env.ts, which fails fast with the exact problem.
|
|
|
|
# development | test | production
|
|
NODE_ENV=development
|
|
# Port the Hono server listens on. The web app proxies /api here.
|
|
PORT=4000
|
|
# User facing origin. Used for links in emails, push payloads and Telegram messages.
|
|
# Must name the same port as apps/web/.env PORT, or better-auth rejects the sign in
|
|
# request as a foreign origin.
|
|
APP_PUBLIC_URL=http://localhost:3005
|
|
|
|
# server = serves HTTP. worker = runs the job poller and sweeps, serves only /healthz.
|
|
ROLE=server
|
|
# Run the job poller inside the server process. Set false only when a dedicated
|
|
# worker exists, which requires Postgres (SQLite is single writer).
|
|
JOBS_INLINE=true
|
|
JOBS_POLL_INTERVAL_MS=2000
|
|
# A running job whose lock is older than this returns to pending, for crash recovery.
|
|
JOBS_STALE_MINUTES=10
|
|
|
|
# sqlite:./data/app.db, sqlite::memory: or postgres://user:pass@host:5432/db
|
|
# The dialect is chosen from this scheme. Nothing else selects it.
|
|
DATABASE_URL=sqlite:./data/app.db
|
|
|
|
# Signing key for sessions. At least 32 characters. Generate: openssl rand -base64 32
|
|
BETTER_AUTH_SECRET=change-me-to-at-least-32-characters-long
|
|
# Public origin cookies are issued for. Auth routes are proxied, so this is the web origin.
|
|
# Keep in step with APP_PUBLIC_URL and apps/web/.env PORT.
|
|
BETTER_AUTH_URL=http://localhost:3005
|
|
|
|
# local | s3. local needs one shared volume across replicas; s3 is required to scale out.
|
|
STORAGE_DRIVER=local
|
|
STORAGE_LOCAL_PATH=./data/files
|
|
# Only read when STORAGE_DRIVER=s3. Bucket, region and both keys are then required.
|
|
S3_ENDPOINT=
|
|
S3_REGION=
|
|
S3_BUCKET=
|
|
S3_ACCESS_KEY_ID=
|
|
S3_SECRET_ACCESS_KEY=
|
|
# Needed by MinIO and most non AWS S3 implementations.
|
|
S3_FORCE_PATH_STYLE=true
|
|
|
|
# Optional. Without it, scans with no QR go straight to the manual form instead of OCR.
|
|
ANTHROPIC_API_KEY=
|
|
OCR_MODEL=claude-sonnet-4-6
|
|
|
|
# Optional. Web push is hidden in the UI when unset. Generate: npx web-push generate-vapid-keys
|
|
PUSH_VAPID_PUBLIC_KEY=
|
|
PUSH_VAPID_PRIVATE_KEY=
|
|
|
|
# Optional. Without SMTP_HOST, verification codes and emails are logged to stdout.
|
|
SMTP_HOST=
|
|
SMTP_PORT=587
|
|
SMTP_USER=
|
|
SMTP_PASS=
|
|
SMTP_FROM=
|
|
|
|
# Optional. Telegram is hidden as a notification channel when unset.
|
|
TELEGRAM_BOT_TOKEN=
|
|
|
|
# Locale for anonymous requests. Signed in users are served their profiles.locale.
|
|
DEFAULT_LOCALE=es
|