Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
150 commits
Select commit Hold shift + click to select a range
96c0d4c
chore(deps): bump the production-dependencies group with 10 updates
dependabot[bot] Apr 27, 2026
4dc5aad
feat: add property management utilities and schemas
JoachimLK Apr 29, 2026
e3d9994
fix: resolve esbuild and typecheck errors in PR validation
JoachimLK Apr 29, 2026
3b9e52b
fix: address CodeRabbit review comments on PR #166
JoachimLK Apr 29, 2026
1371e7d
feat: add ApplicationDetailDrawer and CandidateDetailDrawer components
JoachimLK Apr 30, 2026
349ec6a
feat: enhance property management with new color variables and update…
JoachimLK Apr 30, 2026
c827d56
feat: update color classes for property options to enhance visual con…
JoachimLK Apr 30, 2026
cd7524e
feat: enhance PropertyFilterBar and PropertySchemaEditor with improve…
JoachimLK Apr 30, 2026
486d0e1
feat: improve edit element reference handling in PropertyFilterBar
JoachimLK Apr 30, 2026
a5237a5
feat: add column visibility management to Applications and Candidates…
JoachimLK Apr 30, 2026
a62eea1
Merge pull request #166 from reqcore-inc/feat/properties-and-filters
JoachimLK Apr 30, 2026
b2733f8
fix: update token reference in release-please workflow to use GITHUB_…
JoachimLK Apr 30, 2026
7a57891
fix: update token reference in release-please workflow to prioritize …
JoachimLK Apr 30, 2026
49f0d30
chore: release v1.4.0
JoachimLK Apr 30, 2026
e200b5e
chore(actions): bump googleapis/release-please-action from 4 to 5
dependabot[bot] Apr 30, 2026
d7d8e14
Merge pull request #162 from reqcore-inc/dependabot/npm_and_yarn/prod…
JoachimLK Apr 30, 2026
acd69b6
Merge pull request #161 from reqcore-inc/dependabot/github_actions/go…
JoachimLK Apr 30, 2026
f6fe4ad
Merge pull request #167 from reqcore-inc/release-please--branches--ma…
JoachimLK Apr 30, 2026
6fe4900
feat: implement nonce-based CSP middleware for enhanced security
JoachimLK May 3, 2026
8068e4e
feat: enhance color mode functionality and improve UI responsiveness
JoachimLK May 3, 2026
921ea39
fix: update comments for clarity and enhance rate limiting logic in p…
JoachimLK May 3, 2026
bfb4483
Merge pull request #171 from reqcore-inc/fix/security-and-dependencies
JoachimLK May 3, 2026
3a348b3
chore(deps): bump the production-dependencies group with 14 updates
dependabot[bot] May 4, 2026
66cdf92
Merge pull request #173 from reqcore-inc/dependabot/npm_and_yarn/prod…
JoachimLK May 4, 2026
a1edd32
fix: update overrides to resolve high-severity CVEs blocking dep PRs
JoachimLK May 16, 2026
d375bb7
chore: update package.json dependencies and overrides
JoachimLK May 16, 2026
ee89062
Merge pull request #184 from reqcore-inc/fix/v2-fix-dependencies
JoachimLK May 17, 2026
d076e00
chore: release v1.5.0
JoachimLK May 17, 2026
a5da708
Merge pull request #172 from reqcore-inc/release-please--branches--ma…
JoachimLK Jun 11, 2026
60a723d
chore(deps): update dependencies to latest versions
JoachimLK Jun 11, 2026
9856a9e
Merge pull request #198 from reqcore-inc/fix/zero-pr-dependency-cleanup
JoachimLK Jun 11, 2026
a9aa696
chore(dev-deps): bump the dev-dependencies group with 2 updates
dependabot[bot] Jun 15, 2026
0276ae9
Merge pull request #200 from reqcore-inc/dependabot/npm_and_yarn/dev-…
github-actions[bot] Jun 15, 2026
72433b9
feat: enforce demo account isolation and organization access restrict…
JoachimLK Jun 17, 2026
59dab49
Implement feature X to enhance user experience and optimize performance
JoachimLK Jun 17, 2026
989cca3
feat: handle organization update and delete errors with proper error …
JoachimLK Jun 17, 2026
d533052
test: enhance organization delete error handling in auth client tests
JoachimLK Jun 17, 2026
f47296e
Merge pull request #204 from reqcore-inc/fix/demo-account-org-isolation
JoachimLK Jun 17, 2026
d0f424e
Add Playwright script for sign-in page testing
JoachimLK Jun 17, 2026
de193e5
Fix stalled E2E dependency install
JoachimLK Jun 17, 2026
9b20abd
refactor: remove unused aiScoringChosen state and update form storage…
JoachimLK Jun 18, 2026
69ace61
refactor: remove JobQuestions component to streamline job wizard UI
JoachimLK Jun 18, 2026
5118b6e
feat: add ApplicationBuilderPreview and ApplicationFormBody component…
JoachimLK Jun 18, 2026
b269934
Refactor code structure for improved readability and maintainability
JoachimLK Jun 18, 2026
b128764
feat: enhance job creation wizard with validation and schema updates;…
JoachimLK Jun 19, 2026
9acc0f7
chore: update nodemailer to version 9.0.1 and protobufjs to version 8…
JoachimLK Jun 19, 2026
22fb5c3
Merge remote-tracking branch 'origin/main' into ui/job-wizard-polish
JoachimLK Jun 19, 2026
4975411
chore: remove debug sign-in script
JoachimLK Jun 19, 2026
18bdd9f
feat: enhance job question validation and update schemas; add questio…
JoachimLK Jun 19, 2026
29fa699
fix: improve log handling in migration and S3 bucket readiness checks
JoachimLK Jun 19, 2026
0d9c219
fix: refine rate limiting logic for production environment
JoachimLK Jun 19, 2026
1926a8a
Merge pull request #207 from reqcore-inc/ui/job-wizard-polish
JoachimLK Jun 19, 2026
b2910f8
feat: implement candidate erasure service and GDPR retention logic
JoachimLK Jun 20, 2026
a0e2b58
feat: add end-to-end tests for privacy retention and GDPR compliance …
JoachimLK Jun 20, 2026
7ee6ee3
feat: implement candidate retention and erasure processes
JoachimLK Jun 20, 2026
6e110c3
feat: enhance GDPR retention and erasure processes with improved conf…
JoachimLK Jun 20, 2026
bd2d156
feat: update dialog type for candidate erasure confirmation and refin…
JoachimLK Jun 20, 2026
fbd9461
chore: trigger CI
JoachimLK Jun 20, 2026
dd16794
feat: enable GDPR cleanup sweep in E2E tests and validate cleanup res…
JoachimLK Jun 20, 2026
8692040
Merge pull request #211 from reqcore-inc/feat/gpder-&-data-retention
JoachimLK Jun 21, 2026
89b9b73
chore(dev-deps): bump the dev-dependencies group with 3 updates
dependabot[bot] Jun 22, 2026
92a9832
Merge pull request #213 from reqcore-inc/dependabot/npm_and_yarn/dev-…
github-actions[bot] Jun 22, 2026
86dd691
feat(billing): add billing plans and authorization logic
JoachimLK Jun 24, 2026
c919014
refactor: update comments to clarify indexing rules for public market…
JoachimLK Jun 24, 2026
5625a56
feat: update demo showcase to redirect to sign-in with prefilled demo…
JoachimLK Jun 25, 2026
e6d884e
fix: sync npm lockfile
JoachimLK Jun 25, 2026
24f5136
ci: wait for migration startup log
JoachimLK Jun 25, 2026
c9d702f
fix: tolerate partial stripe billing env
JoachimLK Jun 25, 2026
f7a18f6
feat(ai): implement budget management and observability for AI analys…
JoachimLK Jun 28, 2026
1907e34
chore(dev-deps): bump @playwright/test in the dev-dependencies group
dependabot[bot] Jun 29, 2026
ef820e9
Merge pull request #216 from reqcore-inc/dependabot/npm_and_yarn/dev-…
github-actions[bot] Jun 29, 2026
38e32a9
feat: add public pricing section component and onboarding survey
JoachimLK Jun 29, 2026
0ee11f7
Implement plan feature gating and billing entitlements
JoachimLK Jun 29, 2026
3ed0630
fix(e2e): handle onboarding survey redirect after org creation
JoachimLK Jun 29, 2026
882be6c
Support self-hosted environments in billing checks
JoachimLK Jun 29, 2026
2635c38
Fix billing plan enforcement in tests
JoachimLK Jun 29, 2026
37d1fbb
Fix billing CI checks
JoachimLK Jun 30, 2026
519d666
Refactor AI observability and billing plan enforcement
JoachimLK Jun 30, 2026
ae11e48
Add grandfathered BYOK tier for legacy workspaces
JoachimLK Jun 30, 2026
c68df88
Update grandfather script to include free orgs and exclude demos
JoachimLK Jun 30, 2026
bce9b06
Fix Postgres array type handling in grandfather script
JoachimLK Jun 30, 2026
dd09403
Fix flaky Playwright critical flows
JoachimLK Jun 30, 2026
48a961c
Merge pull request #215 from reqcore-inc/feat/stripe-billing
JoachimLK Jun 30, 2026
d5ddd5e
Remove fixed array length from Postgres client calls
JoachimLK Jun 30, 2026
15b61a4
Transition Reqcore to a closed-source SaaS model
JoachimLK Jul 1, 2026
428d91c
Implement onboarding survey database storage
JoachimLK Jul 1, 2026
ec6c3a0
Merge pull request #218 from reqcore-inc/feat/onboardin-survey
JoachimLK Jul 1, 2026
d5848d1
Transition to open-core model
JoachimLK Jul 3, 2026
b023b71
fix: align self-hosted billing copy
JoachimLK Jul 3, 2026
9c1b05f
Update ConsentBanner styling for light and dark modes
JoachimLK Jul 3, 2026
67ec766
Update README and self-hosting documentation
JoachimLK Jul 3, 2026
e0944b0
Merge pull request #219 from reqcore-inc/feat/open-source-enterprise-…
JoachimLK Jul 3, 2026
cb60ed7
Enable BYOK for Free tier to bypass AI run limits
JoachimLK Jul 3, 2026
f154021
Merge pull request #221 from reqcore-inc/fix/fix-free-tier-byok
JoachimLK Jul 3, 2026
ceeec3c
chore(dev-deps): bump the dev-dependencies group with 2 updates
dependabot[bot] Jul 6, 2026
6fccbd6
Merge pull request #222 from reqcore-inc/dependabot/npm_and_yarn/dev-…
github-actions[bot] Jul 6, 2026
d86e3f7
Add branded career pages
JoachimLK Jul 8, 2026
9185d48
Obfuscate email placeholders in translations
JoachimLK Jul 8, 2026
6938669
Use helper for retrieving published application link
JoachimLK Jul 8, 2026
7c6cee9
Add fullbleed layout support for career page
JoachimLK Jul 8, 2026
ecdabaa
Update AI models and add settings navigation
JoachimLK Jul 8, 2026
f184872
Add middleware to redirect marketing pages to reqcore.com
JoachimLK Jul 8, 2026
9937b4e
Merge remote-tracking branch 'origin/main' into feat/career-page
JoachimLK Jul 8, 2026
e4e9b30
Enable BYOK on all plans and add OpenRouter provider
JoachimLK Jul 8, 2026
3aabee0
Add platform AI configuration support
JoachimLK Jul 8, 2026
ae0f39c
Add configurable AI analysis context to job settings
JoachimLK Jul 9, 2026
53f7244
Implement server-side pagination and filtering for applications
JoachimLK Jul 10, 2026
2c982cb
Add application notes and responsive tab bar to job detail view
JoachimLK Jul 10, 2026
3bbbdcd
Add job application status counts to list endpoint
JoachimLK Jul 10, 2026
5d68596
Make career pages available on all plans
JoachimLK Jul 10, 2026
428d892
Fix SEO for localized job postings
JoachimLK Jul 10, 2026
fb94adf
Fix SEO and indexing for localized UGC pages
JoachimLK Jul 10, 2026
3f2570a
Make candidate resume optional for AI analysis
JoachimLK Jul 10, 2026
9950315
Improve career page UI and banner image processing
JoachimLK Jul 10, 2026
7321b9e
Add banner position control to career pages
JoachimLK Jul 11, 2026
651c4eb
Fix SSR layout flicker in application builder
JoachimLK Jul 11, 2026
57212b9
Refactor DemoUpsellBanner and improve job detail navigation
JoachimLK Jul 11, 2026
a5b5a02
Refactor candidate header layout in job view
JoachimLK Jul 11, 2026
777b56f
Hide navigation bar when a job is active
JoachimLK Jul 11, 2026
7e9bcf6
Merge pull request #223 from reqcore-inc/feat/career-page
JoachimLK Jul 11, 2026
84565e6
Redesign application confirmation page
JoachimLK Jul 11, 2026
5922c94
Remove profile section from job dashboard
JoachimLK Jul 11, 2026
b8b2422
Refactor job detail tabs and section layouts
JoachimLK Jul 11, 2026
b53c93c
Update application confirmation heading text
JoachimLK Jul 12, 2026
94ee02c
Fix flaky job title assertion in application test
JoachimLK Jul 12, 2026
2f8f41b
chore(dev-deps): bump the dev-dependencies group with 4 updates
dependabot[bot] Jul 13, 2026
8ec2bcb
Merge pull request #226 from reqcore-inc/dependabot/npm_and_yarn/dev-…
github-actions[bot] Jul 13, 2026
357c9b1
feat(billing): enable Stripe promotion codes
JoachimLK Jul 15, 2026
0ae894f
Merge pull request #225 from reqcore-inc/feat/application-confirmatio…
JoachimLK Jul 15, 2026
e525490
Refactor interview scheduling and add messaging
JoachimLK Jul 16, 2026
2a941a9
fix interview reschedule type narrowing
JoachimLK Jul 16, 2026
37b5f5c
Refactor database URL resolution for Railway environments
JoachimLK Jul 17, 2026
712ae05
Refactor DatabaseUrlEnvironment to interface
JoachimLK Jul 17, 2026
776121e
Refactor messaging limits to candidate conversations
JoachimLK Jul 17, 2026
b91d945
Add support for candidate message attachments
JoachimLK Jul 17, 2026
60ab423
Add security warning for candidate attachments and enforce payload size
JoachimLK Jul 17, 2026
b671df1
Refactor interview scheduling and messaging UI
JoachimLK Jul 17, 2026
5ed36df
Improve candidate messaging UI and update status handling
JoachimLK Jul 17, 2026
88bdece
Merge pull request #231 from reqcore-inc/feat/candidate-messaging
JoachimLK Jul 18, 2026
36414e6
chore: release v1.6.0
JoachimLK Jul 18, 2026
2df32b5
Implement email verification and anti-abuse safeguards
JoachimLK Jul 18, 2026
08a17ae
Enforce request limits and prevent duplicate interview responses
JoachimLK Jul 18, 2026
22511fa
Merge pull request #232 from reqcore-inc/feat/abuse-prevention-outbou…
JoachimLK Jul 18, 2026
b594096
Defer email verification to outbound actions
JoachimLK Jul 18, 2026
4d90e62
Refactor E2E database URL and verify test accounts
JoachimLK Jul 18, 2026
f8f0313
Add readFileSync to privacy retention test imports
JoachimLK Jul 18, 2026
d07d286
Merge pull request #233 from reqcore-inc/feat/deferred-email-verifica…
JoachimLK Jul 18, 2026
4d08b0b
Merge pull request #205 from reqcore-inc/release-please--branches--ma…
JoachimLK Jul 18, 2026
5cf394c
fix(sync): let the environment override .sync-upstream.conf, and name…
escooterclinic Aug 12, 2026
1a8087b
chore: sync v1.6.0 (dropping upstream .github/workflows)
escooterclinic Aug 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
59 changes: 59 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ S3_BUCKET=reqcore
S3_REGION=us-east-1
S3_FORCE_PATH_STYLE=true

# ─── GDPR retention cleanup ─────────────────────────────────────────────────
# Master switch for automated, irreversible candidate erasure. Fail-closed:
# leave unset/false to guarantee NO automatic deletion. Set to true only after
# you have reviewed your retention policy and want the sweep to run.
GDPR_CLEANUP_ENABLED=false
# Optional: authenticates external schedulers calling /api/admin/retention-cleanup.
CRON_SECRET=

# ─── SEO ─────────────────────────────────────────────────────────────────────
# Used by @nuxtjs/seo for sitemaps, canonical URLs, and OG tags
NUXT_PUBLIC_SITE_URL=http://localhost:3000
Expand Down Expand Up @@ -78,6 +86,19 @@ NUXT_PUBLIC_SITE_URL=http://localhost:3000
# evaluates feature flags locally (no per-request HTTP round trip).
# POSTHOG_FEATURE_FLAGS_KEY=phx_...

# ─── Optional: Platform AI gateway (OpenRouter) ─────────────────────────────
# When set, organizations that haven't added their own AI key fall back to this
# platform key, routed through OpenRouter for unified billing + analytics.
# Platform-paid runs are subject to the budget gate (server/utils/ai/budget.ts);
# bring-your-own-key (BYOK) orgs are never affected. Leave unset to stay BYOK-only.
# Get a key at https://openrouter.ai/keys
# OPENROUTER_API_KEY=sk-or-...
# Default model for platform-paid runs (OpenRouter-prefixed). Default: openai/gpt-5.4-mini
# OPENROUTER_MODEL=openai/gpt-5.4-mini
# Global platform-wide daily AI spend cap in USD — the runaway-loop kill-switch.
# Trips loudly long before a bug can empty your account. Default: 25
# AI_DAILY_SPEND_CAP_USD=25

# ─── Optional: Feature Flag Overrides (no PostHog required) ─────────────────
# Force any flag on or off without running PostHog. The full list of available
# flags lives in shared/feature-flags.ts. Variable name pattern:
Expand Down Expand Up @@ -124,8 +145,21 @@ NUXT_PUBLIC_SITE_URL=http://localhost:3000
# SMTP_SECURE=false # true = implicit TLS (port 465), false = STARTTLS (port 587)

# Option B: Resend (free tier: 3,000 emails/month — resend.com)
# A send-only key is sufficient for ordinary transactional email.
# RESEND_API_KEY=re_xxxxxxxxxxxx
# RESEND_FROM_EMAIL="Reqcore <noreply@yourcompany.com>"
# Candidate messages use the recruiter's name as the display name while this
# setting supplies the mailbox and Reply-To routes each private conversation.
# RESEND_CANDIDATE_FROM_EMAIL="Reqcore Messages <messages@yourcompany.com>"
# Candidate messaging requires a dedicated receiving subdomain and a signed
# webhook subscribed to email.received, sent, delivered, delayed, bounced,
# failed, and complained events at /api/webhooks/resend. Add the Resend-provided
# MX record to the subdomain; do not use the domain of an existing mailbox.
# The Receiving API key must have Full access (a send-only key cannot retrieve
# inbound message bodies).
# RESEND_RECEIVING_API_KEY=re_xxxxxxxxxxxx
# RESEND_REPLY_DOMAIN=reply.yourcompany.com
# RESEND_WEBHOOK_SECRET=whsec_xxxxxxxxxxxx

# ─── Optional: Social Sign-In (Google, GitHub, Microsoft) ────────────────────
# Enable social login buttons on the sign-in and sign-up pages.
Expand All @@ -147,3 +181,28 @@ NUXT_PUBLIC_SITE_URL=http://localhost:3000
# AUTH_MICROSOFT_CLIENT_ID=your-microsoft-client-id
# AUTH_MICROSOFT_CLIENT_SECRET=your-microsoft-client-secret
# AUTH_MICROSOFT_TENANT_ID=common

# ─── Optional: Stripe Billing (paid plans) ───────────────────────────────────
# Enables self-serve subscription checkout for the Solo, Team, and Scale plans.
# Leave STRIPE_SECRET_KEY unset to disable billing entirely (self-hosters are
# unaffected). When STRIPE_SECRET_KEY is set, ALL variables below are required.
#
# Setup:
# 1. Create three Products in Stripe with recurring Prices:
# "Solo" ($79/mo + $790/yr), "Team" ($239/mo + $2,390/yr),
# and "Scale" ($599/mo + $5,990/yr).
# 2. Enable the Customer Portal: Stripe Dashboard → Settings → Billing → Customer portal.
# 3. Add a webhook endpoint → https://yourdomain.com/api/auth/stripe/webhook
# Events: checkout.session.completed, customer.subscription.created/updated/deleted.
# Copy the signing secret into STRIPE_WEBHOOK_SECRET.
# 4. Local dev: run `stripe listen --forward-to localhost:3000/api/auth/stripe/webhook`
# and use the whsec_… it prints.
#
# STRIPE_SECRET_KEY=sk_test_xxx
# STRIPE_WEBHOOK_SECRET=whsec_xxx
# STRIPE_PRICE_SOLO_MONTHLY=price_xxx
# STRIPE_PRICE_SOLO_ANNUAL=price_xxx
# STRIPE_PRICE_TEAM_MONTHLY=price_xxx
# STRIPE_PRICE_TEAM_ANNUAL=price_xxx
# STRIPE_PRICE_SCALE_MONTHLY=price_xxx
# STRIPE_PRICE_SCALE_ANNUAL=price_xxx
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "1.3.0"
".": "1.6.0"
}
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"snyk.advanced.autoSelectOrganization": false
}
}
37 changes: 37 additions & 0 deletions .zed/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"file_scan_exclusions": [
"**/.git",
"**/.svn",
"**/.hg",
"**/.jj",
"**/CVS",
"**/.DS_Store",
"**/Thumbs.db",
"**/.classpath",
"**/.settings",
"**/node_modules",
"**/.nuxt",
"**/.output",
"**/dist",
"**/build",
"**/coverage",
"**/playwright-report",
"**/test-results"
],
"lsp": {
"vtsls": {
"settings": {
"typescript": {
"tsserver": {
"maxTsServerMemory": 2048
}
},
"javascript": {
"tsserver": {
"maxTsServerMemory": 2048
}
}
}
}
}
}
55 changes: 31 additions & 24 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

Reqcore is a **Nuxt 4** full-stack application following a monolithic architecture with clear separation between client (`app/`) and server (`server/`) code. The system supports both **managed deployment** on Railway and **self-hosted deployment** via Docker Compose.
Reqcore is a **Nuxt 4** full-stack application following a monolithic architecture with clear separation between client (`app/`) and server (`server/`) code. Reqcore is open-source and self-hostable; Docker Compose is the reference deployment path for running the app with Postgres and S3-compatible object storage.

## Technology Stack

Expand All @@ -20,7 +20,7 @@ Reqcore is a **Nuxt 4** full-stack application following a monolithic architectu
| SEO | `@nuxtjs/seo` (Sitemap, Robots, Schema.org, SEO Utils, Site Config) | Search engine optimization, structured data |
| Content | `@nuxt/content` v3 | Markdown blog engine with typed collections |
| Infrastructure | Docker Compose (local dev) | Local Postgres, MinIO, Adminer |
| Hosting | Railway | Managed platform (auto-build, auto-deploy) |
| Hosting | Docker Compose / Railway-compatible platforms | Self-hosted or managed deployment |
| CDN | Cloudflare (Free) | DNS, DDoS protection, edge caching |

## Directory Structure
Expand Down Expand Up @@ -80,6 +80,7 @@ reqcore/
│ ├── middleware/ # Global server middleware
│ ├── plugins/
│ │ ├── migrations.ts # Auto-apply migrations on startup
│ │ ├── posthog.ts # PostHog server-side capture + filtered error hook
│ │ └── s3-bucket.ts # Ensure S3 bucket exists + enforce private policy
│ └── utils/ # Auto-imported server utilities
│ ├── auth.ts # Better Auth instance
Expand All @@ -88,14 +89,16 @@ reqcore/
│ ├── requireAuth.ts # Auth guard (throws 401/403)
│ ├── s3.ts # S3/MinIO client, upload, delete, bucket policy
│ ├── slugify.ts # URL slug generation for public job pages
│ ├── rateLimit.ts # IP-based sliding window rate limiter
│ ├── rateLimit.ts # IP-based sliding window rate limiter (in-memory, single-instance)
│ ├── pgDumpEnv.ts # Allowlist of env vars passed to pg_dump (no secret leak)
│ └── schemas/ # Shared Zod validation schemas
│ ├── document.ts # MIME types, file limits, sanitizeFilename()
│ ├── job.ts # Job create/update schemas
│ ├── candidate.ts # Candidate schemas
│ └── application.ts # Application schemas
├── content/ # Markdown content (@nuxt/content v3)
│ └── blog/ # Blog articles (*.md with YAML frontmatter)
├── ee/ # Enterprise Edition — separate license (see ee/LICENSE), a Nuxt layer merged in via `extends`
├── public/ # Static assets
├── docker-compose.yml # Postgres + MinIO + Adminer
├── drizzle.config.ts # Drizzle Kit configuration
Expand Down Expand Up @@ -163,7 +166,7 @@ Nitro auto-imports everything from `server/utils/`. The core utilities are alway
| `auth` | Better Auth instance |
| `env` | Zod-validated environment variables |
| `generateJobSlug` | URL slug generation for public job pages |
| `createRateLimiter` | IP-based sliding window rate limiter |
| `createRateLimiter` | IP-based sliding window rate limiter (in-memory; for multi-instance setups, terminate at the reverse proxy / CDN) |
| `uploadToS3`, `deleteFromS3` | S3/MinIO file operations |

### 3. Environment Validation
Expand Down Expand Up @@ -262,40 +265,44 @@ Blog articles are Markdown files in `content/blog/` powered by `@nuxt/content` v
| Environment secrets | Validated at startup, never exposed to client |
## Deployment Architecture

Reqcore runs on **Railway** with **Cloudflare** as CDN/DNS:
Reqcore can run as a Docker Compose stack or on a managed container platform. The app expects PostgreSQL and S3-compatible object storage.

| Component | Role |
|-----------|------|
| Cloudflare (Free) | DNS, DDoS protection, SSL edge termination, AI bot blocking |
| Railway Service | Nuxt SSR app (auto-built from GitHub via Nixpacks) |
| Railway PostgreSQL | Managed Postgres database with automatic backups |
| Railway Storage Bucket | S3-compatible object storage for documents |
| Reverse proxy / CDN | DNS, TLS termination, DDoS protection |
| Nuxt SSR app | Web UI and Nitro API server |
| PostgreSQL | Application database |
| S3-compatible storage | Uploaded resumes and documents |

### Deploy Workflow

```bash
# Push to main branch — Railway auto-builds and deploys
git push origin main
./setup.sh
docker compose -f docker-compose.production.yml up -d
```

Managed platforms such as Railway can also build from source:

# Build: npm run build (detected from package.json)
# Start: node .output/server/index.mjs
```bash
npm run build
node .output/server/index.mjs
```

### Environment Variables on Railway
### Environment Variables

Variables are configured in the Railway dashboard or via `railway variables`. Service-to-service references use Railway's template syntax:
Configure these variables through `.env`, Docker Compose, or your hosting provider's environment-variable UI:

| Variable | Source |
|----------|--------|
| `DATABASE_URL` | `${{Postgres.DATABASE_URL}}` |
| `S3_ENDPOINT` | `${{Bucket.ENDPOINT}}` |
| `S3_ACCESS_KEY` | `${{Bucket.ACCESS_KEY_ID}}` |
| `S3_SECRET_KEY` | `${{Bucket.SECRET_ACCESS_KEY}}` |
| `S3_BUCKET` | `${{Bucket.BUCKET}}` |
| `S3_REGION` | `${{Bucket.REGION}}` |
| `S3_FORCE_PATH_STYLE` | `false` |
| `BETTER_AUTH_SECRET` | Manual (sealed) |
| `BETTER_AUTH_URL` | Production: `https://reqcore.com` · PR/preview: `https://${{RAILWAY_PUBLIC_DOMAIN}}` |
| `DATABASE_URL` | PostgreSQL connection string |
| `S3_ENDPOINT` | S3-compatible API endpoint |
| `S3_ACCESS_KEY` | S3 access key |
| `S3_SECRET_KEY` | S3 secret key |
| `S3_BUCKET` | Bucket name |
| `S3_REGION` | Bucket region |
| `S3_FORCE_PATH_STYLE` | `true` for MinIO, `false` for virtual-hosted providers |
| `BETTER_AUTH_SECRET` | Random secret, at least 32 characters |
| `BETTER_AUTH_URL` | Public URL of your deployment |

For zero manual PR setup, define `BETTER_AUTH_URL` as `https://${{RAILWAY_PUBLIC_DOMAIN}}` in your Railway preview/PR environment (or shared variables scoped to previews).
## Local Development Services
Expand Down
Loading