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
45 changes: 8 additions & 37 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,37 +1,8 @@
# GhimTech Tax — environment template
# Copy to .env for local development. NEVER commit real secrets.
# See docs/environment.md for the full reference.

# ---- Core ----
GHIMTECH_ENV=development # development | test | staging | production
PORT=4000
HOST=0.0.0.0
NEXT_PUBLIC_API_URL=http://localhost:4000
GHIMTECH_CORS_ORIGIN=http://localhost:3000

# ---- Encryption keys (REQUIRED outside development) ----
# Generate each with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# In staging/production these come from the secret manager, never from files.
GHIMTECH_MASTER_KEY=
GHIMTECH_INDEX_KEY=

# ---- Database ----
# Local: docker compose up postgres
DATABASE_URL=postgresql://ghimtech:ghimtech_dev@localhost:5432/ghimtech_tax
# Set GHIMTECH_STORE=memory to run the API without Postgres (development only).
#GHIMTECH_STORE=memory

# ---- Redis / queues ----
REDIS_URL=redis://localhost:6379
GHIMTECH_API_URL=http://localhost:4000
# Service-account token for the worker (create a dedicated PREPARER-role service user).
GHIMTECH_WORKER_TOKEN=

# ---- E-file provider ----
# mock | sandbox | column-tax | april | generic
# Real transmitter adapters refuse to run until implemented against official
# provider contracts — see docs/efile-providers.md.
GHIMTECH_EFILE_PROVIDER=mock

# ---- Sessions ----
GHIMTECH_SESSION_TTL_MINUTES=30
NEXT_PUBLIC_SITE_URL=https://ghimtech.org
# Server-only HTTPS endpoint that durably receives project enquiries.
PROJECT_WEBHOOK_URL=
PROJECT_WEBHOOK_TOKEN=
# Shared rate limiter. Required for submissions.
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
RATE_LIMIT_SECRET=
72 changes: 8 additions & 64 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,79 +1,23 @@
name: CI

on:
push:
branches: [main]
pull_request:

concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read
jobs:
verify:
name: Lint, typecheck, test, build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Install
run: pnpm install --frozen-lockfile

- name: Format check
run: pnpm format:check

- name: Lint
run: pnpm lint

- name: Typecheck
run: pnpm typecheck

- name: Unit and integration tests
run: pnpm test

- name: Build all apps and packages
run: pnpm build

migrations:
name: Database migration validation
runs-on: ubuntu-latest
services:
postgres:
image: postgres:17-alpine
env:
POSTGRES_USER: ghimtech
POSTGRES_PASSWORD: ghimtech_ci
POSTGRES_DB: ghimtech_tax_ci
ports:
- 5432:5432
options: >-
--health-cmd "pg_isready -U ghimtech"
--health-interval 5s
--health-timeout 3s
--health-retries 10
env:
DATABASE_URL: postgresql://ghimtech:ghimtech_ci@localhost:5432/ghimtech_tax_ci
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Apply migrations to a clean database
working-directory: packages/database
run: pnpm prisma migrate deploy
- name: Verify schema drift
working-directory: packages/database
# The database was just migrated from scratch; comparing it to the
# schema proves migrations fully reproduce the datamodel.
run: pnpm prisma migrate diff --from-url "$DATABASE_URL" --to-schema-datamodel ./prisma/schema.prisma --exit-code
- run: pnpm install --frozen-lockfile
- run: pnpm format:check
- run: pnpm lint
- run: pnpm test
- run: pnpm build
- run: pnpm typecheck
32 changes: 6 additions & 26 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
name: Security

on:
push:
branches: [main]
pull_request:
schedule:
- cron: "0 6 * * 1" # weekly sweep

- cron: "0 6 * * 1"
permissions:
contents: read
jobs:
dependency-audit:
name: Dependency scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -18,33 +17,14 @@ jobs:
with:
node-version: 22
cache: pnpm
- name: Install
run: pnpm install --frozen-lockfile
- name: Audit production dependencies
run: pnpm audit --prod --audit-level=high

- run: pnpm install --frozen-lockfile
- run: pnpm audit --prod --audit-level=high
secret-scan:
name: Secret scanning
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
- uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

container-scan:
name: Container scanning
runs-on: ubuntu-latest
if: github.event_name != 'schedule'
steps:
- uses: actions/checkout@v4
- name: Build API image
run: docker build -f infrastructure/api.Dockerfile -t ghimtech-tax-api:ci .
- name: Install Trivy
run: |
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin
- name: Trivy scan
run: trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 ghimtech-tax-api:ci
19 changes: 0 additions & 19 deletions .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,2 @@
# Gitleaks configuration for GhimTech Tax.
#
# Allowlist covers SYNTHETIC values only:
# - test files use fixed fixture passwords and the public RFC 6238 TOTP
# test vector ("12345678901234567890" in base32)
# - the seed script's development password is documented and reset-forced
# Real secrets are never allowlisted. Anything outside these paths that
# trips a rule must fail the scan.

[extend]
useDefault = true

[allowlist]
description = "Synthetic test fixtures and documented dev-seed credentials"
paths = [
'''.*\.test\.ts$''',
'''apps/api/src/test-helpers\.ts$''',
'''packages/database/prisma/seed\.ts$''',
'''docs/setup\.md$''',
'''README\.md$''',
]
18 changes: 0 additions & 18 deletions CHANGELOG.md

This file was deleted.

99 changes: 39 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,62 @@
# GhimTech Tax
# GhimTech

**GhimTech Tax — Built by GhimTech.** A private professional tax-preparation and e-file platform for federal (Form 1040) and Pennsylvania (PA-40) individual returns, developed and operated by GhimTech.
Software built around how your business actually works.

The initial deployment serves GhimTech's own preparation practice — the owner, family, friends, and a small set of approved clients — on a codebase engineered to production standards so future commercial expansion needs no rewrite.
GhimTech is Durga Ghimeray’s software studio, focused on custom business software, CRM systems, workflow automation, and operational tools. CyanjelHomeCare LLC is the flagship customer.

## What it does
## Application

- **Client management and guided intake** with encrypted identity capture (SSNs and bank numbers are envelope-encrypted; only last-4 is ever displayed)
- **Document vault**: hardened uploads (magic-byte validation, malware scanning), OCR suggestions that always require human verification
- **Deterministic tax engines** for tax year 2025 — federal Form 1040 (standard/itemized deductions, CTC/ODC/ACTC, EITC, AOTC/LLC, dependent care credit, SE tax, QBI simplified, Social Security taxability, preferential capital-gain rates) and PA-40 (income classes, flat 3.07%, Schedule SP tax forgiveness) — with every value traceable to versioned rules and covered by regression tests. **No AI ever computes tax.**
- **Diagnostics** that block unsupported or inconsistent returns from filing
- **A 23-state filing lifecycle** with role-checked transitions, reviewer separation, and mandatory human review
- **Electronic signature** bound to the exact calculation snapshot; any material change invalidates signatures
- **Provider-neutral e-filing** through an authorized transmitter adapter (mock and sandbox providers today; Column Tax / april / other adapters slot in without touching business logic)
- **Hash-chained audit logging** of every sensitive action
The public website uses Next.js App Router, React, and TypeScript in `apps/web`. Pages render on the server; interactive workflow explorers and the enquiry form are small client components. Styling is local CSS with system fonts and no animation library.

## Repository layout
Requirements: Node.js 22 or newer, pnpm 10.33.

```sh
pnpm install --frozen-lockfile
pnpm dev
```
apps/
web/ Next.js application (GhimTech Tax UI)
api/ Fastify REST API
worker/ BullMQ background worker (ack polling, OCR, comms)
packages/
tax-domain/ Normalized return model, lifecycle, permissions, money
tax-year-config/ Versioned per-year rule values (2025)
tax-engine-federal/ Deterministic Form 1040 engine
tax-engine-pennsylvania/ Deterministic PA-40 engine
forms-engine/ Form mapping, snapshots, printable documents
document-processing/ Upload hardening, OCR boundary, verification workflow
efile-core/ Provider contracts, orchestration, rejection dictionary
efile-providers/ Mock, sandbox, and placeholder transmitter adapters
database/ Prisma schema, migrations, seed
security/ Envelope encryption, masking, passwords, TOTP, tokens
audit/ Hash-chained audit events
validation/ Zod schemas and identifier validators
ui/ GhimTech Tax design-system components
testing/ Synthetic taxpayer fixtures (never real data)
infrastructure/ Dockerfiles
docs/ Architecture, security, tax rules, runbooks, ADRs

Open http://localhost:3000.

```sh
pnpm lint
pnpm typecheck
pnpm test
pnpm build
pnpm start
```

## Quick start
## Configuration

Requirements: Node 22+, pnpm 10+, Docker (for Postgres/Redis).
Copy `.env.example` to `apps/web/.env.local` for local development. Configure production values through the hosting provider.

```bash
pnpm install
cp .env.example .env # generate the two keys as instructed inside
- `NEXT_PUBLIC_SITE_URL`: the canonical public origin, defaulting to https://ghimtech.org.
- `PROJECT_WEBHOOK_URL`: an HTTPS endpoint under your control that durably receives enquiries.
- `PROJECT_WEBHOOK_TOKEN`: server-only bearer credential for that endpoint.
- `UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN`: shared Redis service for atomic rate limiting.
- `RATE_LIMIT_SECRET`: random server-only secret used to hash identifiers.

# Fastest path — no database needed (in-memory store, mock e-file provider):
GHIMTECH_STORE=memory pnpm --filter @ghimtech/api dev
pnpm --filter @ghimtech/web dev # in a second terminal → http://localhost:3000
The form fails closed with an explicit, recoverable error when delivery or rate limiting is unconfigured. It does not claim to have received an enquiry when nothing has been delivered.

# Full stack with Postgres:
docker compose up -d
pnpm --filter @ghimtech/database db:migrate:dev
pnpm --filter @ghimtech/database db:seed # synthetic dev users + client
pnpm dev
```
The receiving endpoint must validate the bearer token, honor the `Idempotency-Key` header for at least 24 hours, and acknowledge with 2xx only after durable receipt. Retries keep the same idempotency key for unchanged content. Do not expose these credentials through public environment variables.

Seeded development sign-ins (`GhimTechDev2026!`, password reset + MFA enrollment forced): `admin@dev.ghimtech.test`, `preparer@dev.ghimtech.test`, `reviewer@dev.ghimtech.test`, `client@dev.ghimtech.test`.
On Vercel, the endpoint uses the platform-controlled forwarded IP header. Other hosts use a shared request bucket until trusted proxy handling is explicitly configured. Rate limits are 20 attempts per request-identity bucket and 5 per normalized email address per hour. The application stores hashed rate-limit identifiers with a one-hour expiry.

## Verification
## Content

```bash
pnpm lint && pnpm typecheck && pnpm test && pnpm build
```
- `apps/web/src/lib/content.ts`: service descriptions, projects, workflow modules, and articles.
- `apps/web/src/app/work/cyanjel-homecare/page.tsx`: flagship case study.
- `apps/web/src/app/globals.css`: responsive design system.

The test suite covers the tax engines against hand-computed 2025 scenarios, the full filing lifecycle end-to-end over the real API (including rejection → correction → resubmission), permission and MFA flows, encryption, upload security, and provider contract tests.
The case study separates confirmed customer positioning from illustrative workflow explanations. Specific product capabilities, real screenshots, and measured outcomes require source material or founder confirmation before publication. The project data model supports these fields without inventing them.

## Documentation
For a future case study, add its project data and route, then include it in the Work index. Sitemap entries are derived from the content list.

Start with [docs/architecture.md](docs/architecture.md). Security: [docs/security-model.md](docs/security-model.md) and [docs/threat-model.md](docs/threat-model.md). Tax rules and sources: [docs/tax-rules/](docs/tax-rules/). E-file integration: [docs/efile-providers.md](docs/efile-providers.md). Live status: [docs/PROGRESS.md](docs/PROGRESS.md).
## Deployment

## Important limits (enforced by blocking diagnostics)
The root `vercel.json` retains the existing `apps/web` output location. Use the repository root as the project root. Preview hosts must set `NEXT_PUBLIC_SITE_URL` to their own origin if the form is to be exercised there.

Unsupported situations cannot be e-filed — they surface as ERROR diagnostics and stop the pipeline. Highlights: part-year/nonresident PA returns (modeled, not filable), Schedule C losses or complex businesses, marketplace insurance reconciliation (Form 8962), Form 8995-A QBI, multi-state wages, MFS with Social Security. See [docs/tax-rules/](docs/tax-rules/) for the full list.
Set GHIMTECH_STANDALONE=1 when building a Linux self-hosted image to enable standalone output. Copy the standalone server, `public`, and `.next/static` into the runtime image as documented by Next.js.

---
Read [release notes](docs/release-notes.md) before publishing.

© GhimTech. Author and maintainer: Durga Ghimeray. Private software — not licensed for redistribution.
© GhimTech. Author and maintainer: Durga Ghimeray.
45 changes: 0 additions & 45 deletions apps/api/package.json

This file was deleted.

Loading
Loading