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
2 changes: 1 addition & 1 deletion .agents/plan-reviewer.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Generated from plan-reviewer.md. Do not edit directly.

name = "plan-reviwer"
name = "plan-reviewer"
description = "Reviews plans to ensure they are comprehensive, clear, and actionable for implementation agents. Provides feedback and suggestions for improvement."
model = "gpt-5.5"

Expand Down
11 changes: 11 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.git
node_modules
coverage
dist
.env
.env.*
*.pem
*.key
*.keystore
*.jks
README.md
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Local PostgreSQL service only. Replace only in an untracked .env file.
POSTGRES_DB=quickcop_dev
POSTGRES_USER=quickcop_dev
POSTGRES_PASSWORD=change-me-local-only
POSTGRES_PORT=5432

# Future API configuration: supply real values through a secret manager, never Git.
DATABASE_URL=postgresql://quickcop_dev:change-me-local-only@postgres:5432/quickcop_dev
ADDRESS_ENCRYPTION_KEY=replace-with-a-secret-manager-reference
49 changes: 49 additions & 0 deletions .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Pull request checks

on:
pull_request:

permissions:
contents: read

jobs:
quality:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: npm
- run: npm ci
- run: npm run format:check
- run: npm run lint
- run: npm run typecheck
- run: npm test
- run: npm run coverage
- run: npm run audit
- uses: actions/upload-artifact@v4
if: always()
with:
name: coverage
path: coverage/
if-no-files-found: ignore
secrets:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: gitleaks/gitleaks-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
codeql:
runs-on: ubuntu-24.04
permissions:
contents: read
security-events: write
steps:
- uses: actions/checkout@v4
- uses: github/codeql-action/init@v3
with: { languages: javascript-typescript }
- uses: github/codeql-action/analyze@v3
35 changes: 35 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: Release

on:
push:
tags: ["v*"]
workflow_dispatch:

permissions:
contents: read
id-token: write

jobs:
prerequisites:
runs-on: ubuntu-24.04
environment: production
steps:
- uses: actions/checkout@v4
- name: Verify implementation and release configuration
env:
GCP_PROJECT_ID: ${{ vars.GCP_PROJECT_ID }}
GCP_REGION: ${{ vars.GCP_REGION }}
CLOUD_SQL_INSTANCE: ${{ vars.CLOUD_SQL_INSTANCE }}
API_SERVICE: ${{ vars.CLOUD_RUN_API_SERVICE }}
WORKER_SERVICE: ${{ vars.CLOUD_RUN_WORKER_SERVICE }}
run: |
test -f apps/api/package.json
test -f apps/mobile/package.json
test -n "$GCP_PROJECT_ID" && test -n "$GCP_REGION" && test -n "$CLOUD_SQL_INSTANCE"
test -n "$API_SERVICE" && test -n "$WORKER_SERVICE"
release:
needs: prerequisites
runs-on: ubuntu-24.04
environment: production
steps:
- run: echo 'Implementation-owned release build, migration, Cloud Run deployment, health checks, and Google Play upload will be added when their application entrypoints exist.'
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
node_modules/
dist/
coverage/
reports/
.env
.env.*
!.env.example
*.pem
*.key
*.keystore
*.jks
.expo/
.gradle/
android/.gradle/
postgres-data/
*.log
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
22.14.0
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
coverage
dist
package-lock.json
.agents/
39 changes: 39 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# QuickCop Agent Guide

## Status and source of truth

This repository has infrastructure only. Read `infrastructure_plan.md` before changing tooling, hosting, security, database, release, or stack choices. The plan selects Expo/React Native Android, NestJS, PostgreSQL, Docker for local services, Cloud Run API/worker services (`min-instances >= 1`), and Cloud SQL private IP. Revise the plan with `infra-planner` before changing any of those decisions.

## Repository map

- Front end/mobile: `apps/mobile` — not created yet.
- API/backend: `apps/api` — not created yet.
- Infrastructure: `compose.yaml`, `docker/`, `.env.example`.
- Tooling/tests: `package.json`, TypeScript/ESLint/Jest/Stryker configs, `scripts/`, `tests/`.
- CI: `.github/workflows/pr-checks.yml` and `.github/workflows/release.yml`.
- Documentation: `README.md`, `infrastructure_plan.md`, this file.
- Skills: `.agents/skills/`.

## Required boundaries

- Infrastructure work must not add product screens, API routes, domain models, auth, checkout logic, or production data.
- Do not commit secrets, `.env` files, certificates, reports, generated artifacts, or local database data.
- The API Dockerfile is intentionally unbuildable until application-owned `apps/api` exists; do not add a fake entrypoint merely to make it build.
- Only approved partner APIs may later support checkout. Never collect or store card numbers/CVV.

## Skills and workflow

- Use `infra-planner` for infrastructure decisions and `infra-builder` for plan-approved configuration.
- Use `frontend-ui-engineering` for mobile/UI work, `test-driven-development` for behavior changes, `test-in-browser` or `browser-testing-with-devtools` for browser verification, and `security-and-hardening` for secrets, PII, auth, payments, or integrations.
- Use `documentation-and-adrs` for durable decisions, `code-review-and-quality` before merge, `ci-cd-and-automation` for workflow changes, and `git-workflow-and-versioning` for commits/branches.

## Verification and lifecycle

After installing with `npm ci` on Node 22.14.0, run `npm run verify`, `npm run audit`, and `npm run test:smoke`. CI mirrors the static checks and coverage harness; it additionally runs Gitleaks and CodeQL. `npm run test:smoke` starts then removes the PostgreSQL service and volume. For manual local use, start with `npm run docker:up` and always clean up with `npm run docker:down`.

## Change checklist

1. Read this file, the plan, and applicable local skill instructions.
2. Keep the change scoped; add tests with behavior changes and update documentation for changed developer commands.
3. Run the relevant checks, inspect `git diff --check`, and report unverified prerequisites.
4. Before committing, inspect staged changes for secrets and keep commits focused.
66 changes: 65 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,65 @@
# TechStartup-Template
# QuickCop

Android-first stock tracking and partner-retailer checkout is planned here. The repository currently contains its development infrastructure only; no mobile app, NestJS API, authentication, product model, or checkout behavior has been implemented.

## Repository map

- `infrastructure_plan.md` — approved stack, security, hosting, and release decisions.
- `package.json`, `tsconfig.json`, `eslint.config.mjs`, Jest and Stryker configuration — shared TypeScript quality harness.
- `compose.yaml`, `docker/` — local PostgreSQL and future API image configuration.
- `scripts/smoke-postgres.sh` — disposable PostgreSQL readiness/`SELECT 1` smoke test.
- `tests/` — empty unit and integration test locations for future application tests.
- `.github/workflows/` — pull-request checks and guarded release prerequisite workflow.
- `.agents/skills/` — project-supplied agent guidance.
- `apps/mobile` and `apps/api` — not created yet; application implementation owns them.

## Getting Started

1. Install [Git](https://git-scm.com/downloads), [Docker Desktop or Docker Engine](https://docs.docker.com/get-docker/), and [Node.js 22.14.0 LTS](https://nodejs.org/). Android application developers also need [Android Studio and the Android SDK](https://developer.android.com/studio) plus the JDK required by the selected Gradle/Expo version. Docker does not replace Android tooling or Google Play signing.
2. Copy the safe local-service template, then keep real values untracked:

```bash
cp .env.example .env
```

`.env` is only for local PostgreSQL. Production secrets belong in Google Cloud Secret Manager and GitHub protected-environment secrets, never in source control.

3. Install the locked tooling with Node 22:

```bash
npm ci
```

The current host has Node 18, so this equivalent containerized command is verified here:

```bash
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD":/workspace -w /workspace node:22.14-bookworm-slim npm ci
```

4. Run quality checks and the local database smoke test:

```bash
npm run verify
npm run test:smoke
```

`npm test` and `npm run test:integration` validate an empty harness until application-owned tests exist. `npm run test:smoke` starts PostgreSQL, performs only `SELECT 1`, and stops/removes its local volume.

5. For an interactive local database, run `npm run docker:up`; clean it up with `npm run docker:down`.

## Docker and deployment boundary

`compose.yaml` runs pinned `postgres:17.2-bookworm` locally and exposes it only on `127.0.0.1`. `docker/api.Dockerfile` is a hardened future NestJS image template and cannot build until `apps/api` is created by the application phase.

Production is planned for Cloud Run API and worker services with at least one minimum instance each, plus private-IP Cloud SQL PostgreSQL with automated backups. The release workflow deliberately stops at prerequisites while mobile/API entrypoints and real protected-environment settings are absent; it does not publish, deploy, migrate, or contact Google Cloud.

## GitHub setup required later

Create a `production` protected environment and configure the plan-named `GCP_WORKLOAD_IDENTITY_PROVIDER`, `GCP_SERVICE_ACCOUNT`, `GCP_PROJECT_ID`, `GCP_REGION`, `CLOUD_SQL_INSTANCE`, `CLOUD_RUN_API_SERVICE`, and `CLOUD_RUN_WORKER_SERVICE` variables. Google Play publishing also needs its service-account JSON, Android signing key/password secrets, Google Cloud Workload Identity Federation, Artifact Registry, Cloud Run services, Cloud SQL instance, partner credentials, encryption-key management, and legal/privacy approval.

## Troubleshooting

- **Node version mismatch:** use Node 22.14.0 (`nvm use`) or the documented Node 22 Docker command.
- **Docker permission denied:** ensure Docker Desktop/Engine is running and your user can access the Docker daemon, then retry `npm run test:smoke`.
- **Port 5432 occupied:** change `POSTGRES_PORT` in untracked `.env` and restart the Compose service.
- **Missing environment variable in release:** configure the named GitHub `production` environment variable; the guarded workflow intentionally fails before release actions.
27 changes: 27 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
services:
postgres:
image: postgres:17.2-bookworm
env_file:
- path: .env
required: false
environment:
POSTGRES_DB: ${POSTGRES_DB:-quickcop_dev}
POSTGRES_USER: ${POSTGRES_USER:-quickcop_dev}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-me-local-only}
ports:
- "127.0.0.1:${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s
timeout: 3s
retries: 12
networks: [quickcop]

networks:
quickcop:
driver: bridge

volumes:
postgres-data:
16 changes: 16 additions & 0 deletions docker/api.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Future NestJS API/worker image. It intentionally cannot be built until the
# application implementation creates apps/api and its package manifest.
FROM node:22.14-bookworm-slim AS dependencies
WORKDIR /app
COPY apps/api/package*.json ./
RUN npm ci --omit=dev

FROM node:22.14-bookworm-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production
COPY --from=dependencies /app/node_modules ./node_modules
COPY apps/api/dist ./dist
USER node
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=20s --retries=3 CMD node -e "process.exit(0)"
CMD ["node", "dist/main.js"]
12 changes: 12 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import js from "@eslint/js";
import tseslint from "typescript-eslint";

export default [
{ ignores: ["coverage/**", "node_modules/**", "dist/**"] },
{
files: ["**/*.cjs"],
languageOptions: { globals: { module: "readonly" } },
},
js.configs.recommended,
...tseslint.configs.recommended,
];
Loading
Loading