Skip to content

feat: add documentation for new features including Document Storage, Public Job Board, Application Forms, Dashboard, and Architecture Overview#69

Merged
JoachimLK merged 4 commits intomainfrom
feat/documentation-nuxt-content
Mar 6, 2026
Merged

feat: add documentation for new features including Document Storage, Public Job Board, Application Forms, Dashboard, and Architecture Overview#69
JoachimLK merged 4 commits intomainfrom
feat/documentation-nuxt-content

Conversation

@JoachimLK
Copy link
Copy Markdown
Contributor

@JoachimLK JoachimLK commented Mar 5, 2026

  • Introduced Document Storage feature documentation detailing upload, validation, and security measures.
  • Added Public Job Board documentation covering job listings, SEO optimization, and application flow.
  • Created Application Forms documentation explaining custom question types and management.
  • Documented the Dashboard feature with widgets, navigation, and API integration.
  • Provided an overview of the system architecture, directory structure, data model, and security measures.
  • Included contributing guidelines for development setup and coding conventions.

Summary

  • What does this PR change?
  • Why is this needed?

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Chore

Validation

  • I tested locally
  • I added/updated relevant documentation
  • I verified multi-tenant scoping and auth behavior for affected API paths

DCO

  • All commits in this PR are signed off (Signed-off-by) via git commit -s

Summary by CodeRabbit

  • New Features

    • Added a full Docs section and surfaced Docs links across the site.
  • Documentation

    • Added 20+ comprehensive docs: Getting Started, Deployment, Configuration, Features, Architecture, and Contributing guides.
  • Configuration

    • Marked docs routes for prerendering and added an npm audit policy.
  • Chores

    • Removed Allure reporting integration and related CI workflow/configuration and scripts.

…Public Job Board, Application Forms, Dashboard, and Architecture Overview

- Introduced Document Storage feature documentation detailing upload, validation, and security measures.
- Added Public Job Board documentation covering job listings, SEO optimization, and application flow.
- Created Application Forms documentation explaining custom question types and management.
- Documented the Dashboard feature with widgets, navigation, and API integration.
- Provided an overview of the system architecture, directory structure, data model, and security measures.
- Included contributing guidelines for development setup and coding conventions.
@railway-app railway-app Bot temporarily deployed to applirank / reqcore-pr-69 March 5, 2026 12:02 Destroyed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 5, 2026

📝 Walkthrough

Walkthrough

Adds a full documentation section (content/docs + new docs pages and index), integrates /docs navigation links into site nav and footers, configures content collection and prerender rules, and removes Allure reporting and related CI/config entries.

Changes

Cohort / File(s) Summary
Docs Pages & Index
app/pages/docs/index.vue, app/pages/docs/[...slug].vue
New docs landing and dynamic docs page with sidebar, breadcrumbs, SEO metadata, Prev/Next navigation, and content rendering.
Site Navigation Updates
app/pages/index.vue, app/pages/blog/index.vue, app/pages/blog/[...slug].vue
Added /docs navigation links in top nav and footer locations across homepage and blog pages.
Content Collection + Markdown
content.config.ts, content/docs/**
Added docs content collection and ~25 new markdown docs (Getting Started, Deployment, Features, Architecture, Contributing).
Routing / Build Config
nuxt.config.ts
Added prerender routeRules for /docs and /docs/**.
E2E / Reporting Removal
.github/workflows/allure-pages.yml (deleted), .github/workflows/e2e-tests.yml (Allure steps removed), allurerc.mjs (removed export), package.json (Allure scripts/devDeps removed), playwright.config.ts, .gitignore
Removed Allure configuration, workflows, scripts, devDependencies, reporters, and related gitignore entries; Playwright now emits non-Allure reports.
NPM Config
.npmrc
Added audit-level=high setting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through folders, tidy and spry,
Laid out guides so curious eyes can fly.
From Quick Start dawn to Architecture night,
Breadcrumbs and sidebars gleam by soft moonlight,
Hooray — docs bloom beneath my rabbit sky! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers the main changes with bullet points but fails to complete the required template structure. The summary section and type of change checkboxes lack proper completion, and validation and DCO sections are unchecked without explanation. Complete the template by: filling in the summary section with clear answers to 'What does this PR change?' and 'Why is this needed?', marking the appropriate type of change checkbox (Docs), and confirming validation steps and DCO sign-off status.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately summarizes the main changes—comprehensive documentation additions for features and architecture. It is concise, clear, and specific about the primary change from the developer's perspective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/documentation-nuxt-content

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@railway-app
Copy link
Copy Markdown

railway-app Bot commented Mar 5, 2026

🚅 Deployed to the reqcore-pr-69 environment in applirank

Service Status Web Updated (UTC)
applirank ✅ Success (View Logs) Mar 5, 2026 at 4:25 pm

@railway-app railway-app Bot temporarily deployed to applirank / reqcore-pr-69 March 5, 2026 12:07 Destroyed
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 16

🧹 Nitpick comments (2)
content/docs/4.architecture/1.overview.md (1)

84-95: Data model diagram shows linear workflow, but transitions are bidirectional.

For consistency with the correction needed in content/docs/3.features/1.job-management.md, note that the job status flow shown here (draft → open → closed → archived) is simplified. The actual implementation allows reopening closed jobs and reverting archived jobs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/docs/4.architecture/1.overview.md` around lines 84 - 95, The data
model diagram currently shows a linear job lifecycle "draft → open → closed →
archived" but the system allows bidirectional transitions (e.g., reopening
closed jobs and reverting archived jobs); update the diagram or accompanying
text to reflect reversible transitions by replacing the one-way arrows with
bidirectional arrows (e.g., draft ↔ open ↔ closed ↔ archived or explicitly
annotate that closed and archived can be reverted) and add a short clarifying
note that job statuses (draft, open, closed, archived) are not strictly terminal
and can transition backward.
app/pages/docs/[...slug].vue (1)

137-170: Extract shared docs nav/footer to reduce duplication.

This markup is duplicated across docs pages and will drift. Consider moving it to shared components/layout.

♻️ Refactor direction
-    <nav ...>...</nav>
+    <DocsTopNav :session="session" active="docs" />
@@
-    <footer ...>...</footer>
+    <DocsFooter />

Also applies to: 267-283

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/docs/`[...slug].vue around lines 137 - 170, The docs
navigation/footer markup is duplicated; extract the <nav> block (including the
NuxtLink entries, Github component usage, and session?.user conditional
Dashboard/Sign In links) into a reusable component (e.g., DocsNav.vue or
SharedNav.vue) and similarly extract the footer into a DocsFooter.vue or include
both in a shared DocsLayout; then import and use that component/layout in pages
like the current docs/[...slug].vue and other docs pages to remove the
duplicated markup and centralize future updates.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/pages/docs/`[...slug].vue:
- Around line 147-153: Update the icon-only external anchor that wraps the
Github component (the <a ... class="transition hover:text-white"> containing
<Github class="size-4" />) to include rel="noopener noreferrer" alongside
target="_blank" and add an accessible name (e.g., aria-label="Open ReqCore on
GitHub") so screen readers can describe the link; apply the same two changes to
the other identical GitHub anchor instance in the file (the second <a> wrapping
<Github />).

In `@app/pages/docs/index.vue`:
- Around line 128-134: The external GitHub anchor that wraps the Github
component uses target="_blank" but lacks rel protection and an accessible name;
update the anchor (the <a> that contains the Github component) to include
rel="noopener noreferrer" and add an accessible label (e.g., aria-label="Open
Reqcore on GitHub" or include a visually hidden text node) so screen readers can
identify the link; apply the same changes to the other identical anchor (the one
around lines 229-232).
- Around line 90-96: The index page currently only renders items from the
hard-coded sections array (sections: DocSection[]) so any docs with computed
doc.section || 'Other' will be omitted; update the rendering logic to derive the
displayed sections dynamically by merging the existing static sections with any
additional section keys discovered from the docs collection (use the same
key/title/description/icon shape as in sections), or replace the static sections
with a computedSections getter that returns [...sections, ...extraSections]
where extraSections is built from docs.map(d => d.section || 'Other')
deduplicated, and ensure the component that uses sections (the list renderer)
references this computedSections instead of the static sections variable (look
for usages of sections and doc.section || 'Other' in the file).

In `@content/docs/1.getting-started/3.configuration.md`:
- Around line 27-40: Add a short clarifying note under "Optional Variables" that
the four client-exposed vars LIVE_DEMO_EMAIL, LIVE_DEMO_SECRET,
NUXT_PUBLIC_GISCUS_REPO_ID and NUXT_PUBLIC_GISCUS_CATEGORY_ID are read directly
from process.env in nuxt.config.ts and exposed via runtimeConfig.public, and
therefore are not validated by the Zod schema in server/utils/env.ts (they will
not cause startup failures if missing/malformed); reference those variable names
and the two files (nuxt.config.ts and server/utils/env.ts) so readers can locate
where validation does and does not occur.
- Around line 14-26: The README incorrectly marks S3_REGION as required; update
the docs to reflect that S3_REGION is optional with default 'us-east-1' per
server/utils/env.ts where S3_REGION is defined as
.optional().default('us-east-1'). Move the `S3_REGION` row from the "Required
Variables" table into the "Optional Variables" table and adjust its
description/example to indicate it's optional and defaults to us-east-1.

In `@content/docs/2.deployment/1.docker-compose.md`:
- Line 94: Replace the misspelled reverse proxy name "Traefin" with the correct
"Traefik" in the list item that begins "1. **Put a reverse proxy in front**
(Nginx, Caddy, or Traefin) with TLS termination" so the sentence reads "(Nginx,
Caddy, or Traefik)"; update the string literal occurrence "Traefin" wherever it
appears in that document to "Traefik".
- Around line 24-26: Clarify the Quick Start flow to avoid port conflicts:
either document that docker compose is the full-stack solution (remove the
host-side steps `npm install`/`npm run dev` and state that the app is served by
the container started via `docker compose up -d`, which uses the Dockerfile
Stage 2 CMD ["node", ".output/server/index.mjs"] on port 3000), or present
Docker Compose as a backend-only option (remove the `app` service from the
compose example and state that compose only runs `db` and `minio` while
developers run the Nuxt dev server on the host with `npm run dev`); update the
Quick Start text and the architecture notes so they explicitly state which mode
is intended and avoid running both containerized CMD and host `npm run dev`
binding to port 3000 simultaneously.

In `@content/docs/2.deployment/3.environment-variables.md`:
- Around line 12-26: Update the docs to reflect that S3_REGION is optional with
a default of "us-east-1" (see server/utils/env.ts where S3_REGION default is
applied) and that BETTER_AUTH_URL is conditionally required (it is validated in
the env schema's superRefine logic — only required outside Railway PR/preview
environments where RAILWAY_PUBLIC_DOMAIN is used to derive the value); change
the table entries accordingly to mark S3_REGION as optional with default and
BETTER_AUTH_URL as conditionally required with a note about Railway preview
derivation.

In `@content/docs/3.features/1.job-management.md`:
- Around line 14-27: The docs incorrectly claim transitions are forward-only;
update the job lifecycle text in content/docs/3.features/1.job-management.md to
reflect the actual allowed transitions implemented in
shared/status-transitions.ts (e.g., allow closed → open and archived →
draft/open), replace the linear "Draft → Open → Closed → Archived" wording and
the final sentence with a diagram or sentence stating that transitions are
validated server-side and that closed jobs can be reopened and archived jobs can
be reverted to draft or open (mentioning the file shared/status-transitions.ts
as the source of truth).

In `@content/docs/3.features/2.candidate-pipeline.md`:
- Around line 14-19: Update the pipeline transitions block to reflect the real
allowed transitions instead of implying a strictly linear flow: replace the
current arrow diagram with the explicit map using the status identifiers (new,
screening, interview, offer, hired, rejected) — e.g. "new -> screening |
interview | rejected", "screening -> interview | offer | rejected", "interview
-> offer | rejected", "offer -> hired | rejected", "hired -> (terminal)",
"rejected -> new" — and update the "Status transitions" sentence to read "Move
the candidate to any allowed next status" so the docs and UI/API behavior align
with the actual transition rules.

In `@content/docs/3.features/5.application-forms.md`:
- Around line 53-55: The fenced code block containing the line
"/jobs/{slug}/apply" is missing a fence language and triggers markdownlint
MD040; update that block (the triple-backtick fence surrounding
"/jobs/{slug}/apply") to include a language identifier such as text or bash
(e.g., change ``` to ```text) so the block has an explicit language.

In `@content/docs/3.features/6.dashboard.md`:
- Around line 76-78: The fenced code block containing the endpoint "GET
/api/dashboard/stats" is missing a language tag; update that code fence (the
block that currently contains just GET /api/dashboard/stats) to include a
language tag such as "http" (e.g., ```http) to satisfy markdownlint MD040 and
remove the warning.

In `@content/docs/4.architecture/2.directory-structure.md`:
- Around line 14-82: The fenced directory-tree block uses plain triple backticks
without a language tag; update the opening fence in the block that lists the
repo tree (the ``````` reqcore/ … ``` block) to include a language identifier
such as "text" (i.e., change ``` to ```text) so the MD040 lint warning is
resolved and the tree renders as plain text.

In `@content/docs/4.architecture/3.data-model.md`:
- Around line 31-77: Update the documented table definitions to match the actual
schema: in the `job` table replace `employmentType` with `type` and add the
`requireResume` and `requireCoverLetter` columns; in the `candidate` table
either add the `notes` column if present in schema or remove it from the docs to
match `candidate`'s actual columns; in the `application` table add
`coverLetterText` to the column list. Use the exact column identifiers (`type`,
`requireResume`, `requireCoverLetter`, `notes`, `coverLetterText`) and update
the descriptions/column types to mirror `server/database/schema/app.ts` so docs
and schema are consistent.

In `@content/docs/5.contributing/2.coding-conventions.md`:
- Around line 65-71: The fenced route-mapping block showing the API paths (the
three backtick block containing lines like "server/api/jobs/index.get.ts → GET
/api/jobs" and the other route mappings) lacks a language tag and triggers
markdownlint MD040; fix it by adding a language identifier (use "text") to the
opening fence so the block becomes ```text and the rest of the content remains
unchanged.

In `@nuxt.config.ts`:
- Around line 191-196: The current top-level content.highlight setting must be
moved under the build->markdown tree: remove the existing content.highlight
entry and add it as content.build.markdown.highlight with the same theme value
(i.e., move the 'highlight' object from the top-level 'content' config into
'content.build.markdown.highlight'); update the 'content' object in nuxt config
so the 'highlight' key lives at content.build.markdown.highlight (preserving
theme: 'one-dark-pro').

---

Nitpick comments:
In `@app/pages/docs/`[...slug].vue:
- Around line 137-170: The docs navigation/footer markup is duplicated; extract
the <nav> block (including the NuxtLink entries, Github component usage, and
session?.user conditional Dashboard/Sign In links) into a reusable component
(e.g., DocsNav.vue or SharedNav.vue) and similarly extract the footer into a
DocsFooter.vue or include both in a shared DocsLayout; then import and use that
component/layout in pages like the current docs/[...slug].vue and other docs
pages to remove the duplicated markup and centralize future updates.

In `@content/docs/4.architecture/1.overview.md`:
- Around line 84-95: The data model diagram currently shows a linear job
lifecycle "draft → open → closed → archived" but the system allows bidirectional
transitions (e.g., reopening closed jobs and reverting archived jobs); update
the diagram or accompanying text to reflect reversible transitions by replacing
the one-way arrows with bidirectional arrows (e.g., draft ↔ open ↔ closed ↔
archived or explicitly annotate that closed and archived can be reverted) and
add a short clarifying note that job statuses (draft, open, closed, archived)
are not strictly terminal and can transition backward.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5d27249a-e3a9-4fc4-b6d7-5ec5bc06ff93

📥 Commits

Reviewing files that changed from the base of the PR and between 94b5cda and 625113a.

📒 Files selected for processing (26)
  • app/pages/blog/[...slug].vue
  • app/pages/blog/index.vue
  • app/pages/docs/[...slug].vue
  • app/pages/docs/index.vue
  • app/pages/index.vue
  • content.config.ts
  • content/docs/1.getting-started/1.introduction.md
  • content/docs/1.getting-started/2.installation.md
  • content/docs/1.getting-started/3.configuration.md
  • content/docs/1.getting-started/4.quick-start.md
  • content/docs/2.deployment/1.docker-compose.md
  • content/docs/2.deployment/2.railway.md
  • content/docs/2.deployment/3.environment-variables.md
  • content/docs/3.features/1.job-management.md
  • content/docs/3.features/2.candidate-pipeline.md
  • content/docs/3.features/3.document-storage.md
  • content/docs/3.features/4.public-job-board.md
  • content/docs/3.features/5.application-forms.md
  • content/docs/3.features/6.dashboard.md
  • content/docs/4.architecture/1.overview.md
  • content/docs/4.architecture/2.directory-structure.md
  • content/docs/4.architecture/3.data-model.md
  • content/docs/4.architecture/4.security.md
  • content/docs/5.contributing/1.development-setup.md
  • content/docs/5.contributing/2.coding-conventions.md
  • nuxt.config.ts

Comment on lines +147 to +153
<a
href="https://github.com/reqcore-inc/reqcore"
target="_blank"
class="transition hover:text-white"
>
<Github class="size-4" />
</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Harden external links and label the icon-only GitHub link.

Please add rel="noopener noreferrer" on target="_blank" links, and add an accessible name on the icon-only nav link.

🔧 Suggested patch
           <a
             href="https://github.com/reqcore-inc/reqcore"
             target="_blank"
+            rel="noopener noreferrer"
+            aria-label="Reqcore GitHub repository"
             class="transition hover:text-white"
           >
             <Github class="size-4" />
           </a>
@@
           <a
             href="https://github.com/reqcore-inc/reqcore"
             target="_blank"
+            rel="noopener noreferrer"
             class="transition hover:text-white/60"
           >
             GitHub
           </a>

Also applies to: 274-277

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/docs/`[...slug].vue around lines 147 - 153, Update the icon-only
external anchor that wraps the Github component (the <a ... class="transition
hover:text-white"> containing <Github class="size-4" />) to include
rel="noopener noreferrer" alongside target="_blank" and add an accessible name
(e.g., aria-label="Open ReqCore on GitHub") so screen readers can describe the
link; apply the same two changes to the other identical GitHub anchor instance
in the file (the second <a> wrapping <Github />).

Comment thread app/pages/docs/index.vue
Comment on lines +90 to +96
const sections: DocSection[] = [
{ key: 'Getting Started', title: 'Getting Started', description: 'Install, configure, and start using Reqcore', icon: Rocket },
{ key: 'Deployment', title: 'Deployment', description: 'Self-host with Docker or deploy to Railway', icon: Container },
{ key: 'Features', title: 'Features', description: 'Jobs, pipeline, documents, and job board', icon: Briefcase },
{ key: 'Architecture', title: 'Architecture', description: 'System design, data model, and security', icon: Layers },
{ key: 'Contributing', title: 'Contributing', description: 'Development setup and coding conventions', icon: Code },
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Docs in non-predefined sections are grouped but never displayed.

doc.section || 'Other' is computed, but the UI only renders the fixed sections array. Any unexpected section becomes hidden from the index.

🔧 Suggested patch
 const docsBySection = computed(() => {
   if (!allDocs.value) return {}
   const grouped: Record<string, typeof allDocs.value> = {}
   for (const doc of allDocs.value) {
     const section = doc.section || 'Other'
     if (!grouped[section]) grouped[section] = []
     grouped[section].push(doc)
   }
   return grouped
 })
+
+const visibleSections = computed<DocSection[]>(() => {
+  const known = new Set(sections.map(section => section.key))
+  const extra: DocSection[] = Object.keys(docsBySection.value)
+    .filter(sectionKey => !known.has(sectionKey))
+    .map(sectionKey => ({
+      key: sectionKey,
+      title: sectionKey,
+      description: 'Additional documentation',
+      icon: BookOpen,
+    }))
+  return [...sections, ...extra]
+})
-      <div v-for="section in sections" :key="section.key" class="mb-12">
+      <div v-for="section in visibleSections" :key="section.key" class="mb-12">

Also applies to: 99-108, 178-178

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/docs/index.vue` around lines 90 - 96, The index page currently only
renders items from the hard-coded sections array (sections: DocSection[]) so any
docs with computed doc.section || 'Other' will be omitted; update the rendering
logic to derive the displayed sections dynamically by merging the existing
static sections with any additional section keys discovered from the docs
collection (use the same key/title/description/icon shape as in sections), or
replace the static sections with a computedSections getter that returns
[...sections, ...extraSections] where extraSections is built from docs.map(d =>
d.section || 'Other') deduplicated, and ensure the component that uses sections
(the list renderer) references this computedSections instead of the static
sections variable (look for usages of sections and doc.section || 'Other' in the
file).

Comment thread app/pages/docs/index.vue
Comment on lines +128 to +134
<a
href="https://github.com/reqcore-inc/reqcore"
target="_blank"
class="transition hover:text-white"
>
<Github class="size-4" />
</a>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add rel protection and an accessible name for the icon-only external link.

Please harden target="_blank" links and ensure the icon-only GitHub link has an accessible label.

🔧 Suggested patch
           <a
             href="https://github.com/reqcore-inc/reqcore"
             target="_blank"
+            rel="noopener noreferrer"
+            aria-label="Reqcore GitHub repository"
             class="transition hover:text-white"
           >
             <Github class="size-4" />
           </a>
@@
           <a
             href="https://github.com/reqcore-inc/reqcore"
             target="_blank"
+            rel="noopener noreferrer"
             class="transition hover:text-white/60"
           >
             GitHub
           </a>

Also applies to: 229-232

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/docs/index.vue` around lines 128 - 134, The external GitHub anchor
that wraps the Github component uses target="_blank" but lacks rel protection
and an accessible name; update the anchor (the <a> that contains the Github
component) to include rel="noopener noreferrer" and add an accessible label
(e.g., aria-label="Open Reqcore on GitHub" or include a visually hidden text
node) so screen readers can identify the link; apply the same changes to the
other identical anchor (the one around lines 229-232).

Comment on lines +14 to +26
### Required Variables

| Variable | Description | Example |
|----------|-------------|---------|
| `DATABASE_URL` | PostgreSQL connection string | `postgresql://user:pass@localhost:5432/reqcore` |
| `BETTER_AUTH_SECRET` | Session signing secret (min 32 chars) | Generated by `setup.sh` |
| `BETTER_AUTH_URL` | Public URL of the application | `http://localhost:3000` |
| `S3_ENDPOINT` | S3-compatible storage endpoint | `http://localhost:9000` |
| `S3_ACCESS_KEY` | Storage access key | `minioadmin` |
| `S3_SECRET_KEY` | Storage secret key | `minioadmin` |
| `S3_BUCKET` | Storage bucket name | `reqcore` |
| `S3_REGION` | Storage region | `us-east-1` |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

S3_REGION is optional with a default, not required.

Per server/utils/env.ts (lines 58-59), S3_REGION is defined as .optional().default('us-east-1'). It should be moved to the optional variables section.

📝 Suggested fix

Move S3_REGION from the Required Variables table to the Optional Variables section:

 | `S3_BUCKET` | Storage bucket name | `reqcore` |
-| `S3_REGION` | Storage region | `us-east-1` |

 ### Optional Variables

 | Variable | Description | Default |
 |----------|-------------|---------|
+| `S3_REGION` | Storage region | `us-east-1` |
 | `S3_FORCE_PATH_STYLE` | Use path-style S3 URLs (required for MinIO) | `true` |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/docs/1.getting-started/3.configuration.md` around lines 14 - 26, The
README incorrectly marks S3_REGION as required; update the docs to reflect that
S3_REGION is optional with default 'us-east-1' per server/utils/env.ts where
S3_REGION is defined as .optional().default('us-east-1'). Move the `S3_REGION`
row from the "Required Variables" table into the "Optional Variables" table and
adjust its description/example to indicate it's optional and defaults to
us-east-1.

Comment on lines +27 to +40
### Optional Variables

| Variable | Description | Default |
|----------|-------------|---------|
| `S3_FORCE_PATH_STYLE` | Use path-style S3 URLs (required for MinIO) | `true` |
| `NUXT_PUBLIC_SITE_URL` | Public site URL for SEO | `https://reqcore.com` |
| `DEMO_ORG_SLUG` | Show read-only demo banner for this org | *(empty)* |
| `LIVE_DEMO_EMAIL` | Prefill sign-in with demo email | `demo@reqcore.com` |
| `LIVE_DEMO_SECRET` | Prefill sign-in with demo password | `demo1234` |
| `GITHUB_FEEDBACK_TOKEN` | GitHub PAT for in-app feedback | *(empty)* |
| `GITHUB_FEEDBACK_REPO` | GitHub repo for feedback issues | *(empty)* |
| `NUXT_PUBLIC_GISCUS_REPO_ID` | Giscus repo node ID for comments | *(empty)* |
| `NUXT_PUBLIC_GISCUS_CATEGORY_ID` | Giscus category node ID for comments | *(empty)* |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Clarify that some optional variables are not Zod-validated.

LIVE_DEMO_EMAIL, LIVE_DEMO_SECRET, NUXT_PUBLIC_GISCUS_REPO_ID, and NUXT_PUBLIC_GISCUS_CATEGORY_ID are read directly from process.env in nuxt.config.ts (lines 100-122) and exposed via runtimeConfig.public. They are not validated by the Zod schema in server/utils/env.ts and won't cause startup failures if missing/malformed.

Consider adding a note to distinguish these client-side config vars from the Zod-validated server vars.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/docs/1.getting-started/3.configuration.md` around lines 27 - 40, Add
a short clarifying note under "Optional Variables" that the four client-exposed
vars LIVE_DEMO_EMAIL, LIVE_DEMO_SECRET, NUXT_PUBLIC_GISCUS_REPO_ID and
NUXT_PUBLIC_GISCUS_CATEGORY_ID are read directly from process.env in
nuxt.config.ts and exposed via runtimeConfig.public, and therefore are not
validated by the Zod schema in server/utils/env.ts (they will not cause startup
failures if missing/malformed); reference those variable names and the two files
(nuxt.config.ts and server/utils/env.ts) so readers can locate where validation
does and does not occur.

Comment on lines +76 to +78
```
GET /api/dashboard/stats
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add a language tag to the fenced block.

The endpoint code fence is unlabeled; markdownlint MD040 will keep warning here.

Suggested fix
-```
+```http
 GET /api/dashboard/stats
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @content/docs/3.features/6.dashboard.md around lines 76 - 78, The fenced code
block containing the endpoint "GET /api/dashboard/stats" is missing a language
tag; update that code fence (the block that currently contains just GET
/api/dashboard/stats) to include a language tag such as "http" (e.g., ```http)
to satisfy markdownlint MD040 and remove the warning.


</details>

<!-- fingerprinting:phantom:poseidon:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +14 to +82
```
reqcore/
├── app/ # Client source (Nuxt 4 srcDir)
│ ├── app.vue # Root component
│ ├── assets/
│ │ └── css/main.css # Tailwind CSS entry + @theme tokens
│ ├── components/ # Auto-imported Vue components
│ ├── composables/ # Auto-imported composables (useXxx)
│ ├── layouts/ # Layout components
│ │ ├── dashboard.vue # Sidebar + main content
│ │ ├── auth.vue # Centered card for auth pages
│ │ └── public.vue # Simple header/footer for public pages
│ ├── middleware/ # Client-side route middleware
│ ├── pages/ # File-based routing
│ │ ├── index.vue # Landing page (dark theme)
│ │ ├── roadmap.vue # Public roadmap
│ │ ├── blog/ # Blog listing + detail
│ │ ├── docs/ # Documentation listing + detail
│ │ ├── catalog/ # Feature catalog
│ │ ├── jobs/ # Public job board
│ │ ├── auth/ # Sign-in / sign-up
│ │ ├── dashboard/ # Authenticated dashboard
│ │ └── onboarding/ # Org creation flow
│ ├── plugins/ # Client-side Nuxt plugins
│ └── utils/ # Auto-imported utilities
│ └── auth-client.ts # Better Auth Vue client
├── server/ # Nitro server (at project root)
│ ├── api/ # API route handlers
│ │ ├── auth/[...all].ts # Better Auth catch-all
│ │ ├── jobs/ # Job CRUD + questions
│ │ ├── candidates/ # Candidate CRUD + documents
│ │ ├── applications/ # Application CRUD
│ │ ├── documents/ # Document access endpoints
│ │ ├── dashboard/ # Dashboard stats
│ │ └── public/jobs/ # Unauthenticated job board API
│ ├── database/
│ │ ├── schema/ # Drizzle ORM table definitions
│ │ │ ├── app.ts # Domain tables (job, candidate, etc.)
│ │ │ ├── auth.ts # Better Auth tables (DO NOT MODIFY)
│ │ │ └── index.ts # Re-exports
│ │ └── migrations/ # Generated SQL migrations
│ ├── middleware/ # Global server middleware
│ ├── plugins/
│ │ ├── migrations.ts # Auto-apply migrations on startup
│ │ └── s3-bucket.ts # Ensure S3 bucket exists + enforce private policy
│ └── utils/ # Auto-imported server utilities
│ ├── auth.ts # Better Auth instance
│ ├── db.ts # Drizzle client + connection pool
│ ├── env.ts # Zod-validated environment variables
│ ├── requireAuth.ts # Auth guard (throws 401/403)
│ ├── s3.ts # S3/MinIO client, upload, delete
│ ├── slugify.ts # URL slug generation
│ ├── rateLimit.ts # IP-based sliding window rate limiter
│ └── schemas/ # Zod validation schemas
├── content/ # @nuxt/content v3 collections
│ ├── blog/ # Blog articles (Markdown)
│ ├── catalog/ # Feature catalog items
│ └── docs/ # Documentation pages
├── shared/ # Shared between app and server
├── public/ # Static assets (favicon, images)
├── i18n/ # Internationalization
│ └── locales/ # Translation JSON files
├── e2e/ # Playwright end-to-end tests
├── nuxt.config.ts # Nuxt configuration
├── content.config.ts # Content collection definitions
├── drizzle.config.ts # Drizzle Kit configuration
├── docker-compose.yml # PostgreSQL + MinIO + Adminer
└── package.json
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Label the directory-tree code fence.

The large fenced block is missing a language identifier (MD040).

Suggested fix
-```
+```text
 reqcore/
 ...
</details>

<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

```suggestion

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 14-14: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/docs/4.architecture/2.directory-structure.md` around lines 14 - 82,
The fenced directory-tree block uses plain triple backticks without a language
tag; update the opening fence in the block that lists the repo tree (the ```````
reqcore/ … ``` block) to include a language identifier such as "text" (i.e.,
change ``` to ```text) so the MD040 lint warning is resolved and the tree
renders as plain text.

Comment on lines +31 to +77
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `title` | `string` | Job title |
| `description` | `text` | Full description (Markdown) |
| `status` | `enum` | `draft`, `open`, `closed`, `archived` |
| `location` | `string` | Office location |
| `employmentType` | `string` | Full-time, Part-time, etc. |
| `slug` | `string` | URL slug for public page |
| `salaryMin` / `salaryMax` | `integer` | Salary range |
| `salaryCurrency` | `string` | Currency code (USD, EUR, etc.) |
| `salaryUnit` | `string` | HOUR, DAY, WEEK, MONTH, YEAR |
| `remoteStatus` | `string` | On-site, Remote, Hybrid |
| `validThrough` | `timestamp` | Application deadline |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |

### `candidate`

A person who has applied or been added to the talent pool.

| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `firstName` / `lastName` | `string` | Full name |
| `email` | `string` | Email (unique per org) |
| `phone` | `string` | Phone number |
| `notes` | `text` | Recruiter notes |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |

**Unique constraint**: `(organizationId, email)` — prevents duplicate candidates within an org.

### `application`

Links a candidate to a job with a pipeline status.

| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `jobId` | `uuid` | FK → job |
| `candidateId` | `uuid` | FK → candidate |
| `status` | `enum` | `new`, `screening`, `interview`, `offer`, `hired`, `rejected` |
| `notes` | `text` | Application-specific notes |
| `score` | `integer` | Recruiter-assigned score |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Data model tables are out of sync with the actual schema.

Several documented columns don’t match server/database/schema/app.ts:

  • job: employmentType should be type, and requireResume / requireCoverLetter are missing.
  • candidate: notes is documented but not present.
  • application: coverLetterText exists in schema but is missing here.

This should be aligned before merge to avoid incorrect query/code assumptions.

Suggested doc corrections (example)
-| `employmentType` | `string` | Full-time, Part-time, etc. |
+| `type` | `enum` | `full_time`, `part_time`, `contract`, `internship` |
+| `requireResume` | `boolean` | Whether resume is required on application form |
+| `requireCoverLetter` | `boolean` | Whether cover letter is required on application form |
...
-| `notes` | `text` | Recruiter notes |
...
 | `notes` | `text` | Application-specific notes |
 | `score` | `integer` | Recruiter-assigned score |
+| `coverLetterText` | `text` | Parsed/submitted cover letter text |
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `title` | `string` | Job title |
| `description` | `text` | Full description (Markdown) |
| `status` | `enum` | `draft`, `open`, `closed`, `archived` |
| `location` | `string` | Office location |
| `employmentType` | `string` | Full-time, Part-time, etc. |
| `slug` | `string` | URL slug for public page |
| `salaryMin` / `salaryMax` | `integer` | Salary range |
| `salaryCurrency` | `string` | Currency code (USD, EUR, etc.) |
| `salaryUnit` | `string` | HOUR, DAY, WEEK, MONTH, YEAR |
| `remoteStatus` | `string` | On-site, Remote, Hybrid |
| `validThrough` | `timestamp` | Application deadline |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
### `candidate`
A person who has applied or been added to the talent pool.
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `firstName` / `lastName` | `string` | Full name |
| `email` | `string` | Email (unique per org) |
| `phone` | `string` | Phone number |
| `notes` | `text` | Recruiter notes |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
**Unique constraint**: `(organizationId, email)` — prevents duplicate candidates within an org.
### `application`
Links a candidate to a job with a pipeline status.
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `jobId` | `uuid` | FK → job |
| `candidateId` | `uuid` | FK → candidate |
| `status` | `enum` | `new`, `screening`, `interview`, `offer`, `hired`, `rejected` |
| `notes` | `text` | Application-specific notes |
| `score` | `integer` | Recruiter-assigned score |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `title` | `string` | Job title |
| `description` | `text` | Full description (Markdown) |
| `status` | `enum` | `draft`, `open`, `closed`, `archived` |
| `location` | `string` | Office location |
| `type` | `enum` | `full_time`, `part_time`, `contract`, `internship` |
| `requireResume` | `boolean` | Whether resume is required on application form |
| `requireCoverLetter` | `boolean` | Whether cover letter is required on application form |
| `slug` | `string` | URL slug for public page |
| `salaryMin` / `salaryMax` | `integer` | Salary range |
| `salaryCurrency` | `string` | Currency code (USD, EUR, etc.) |
| `salaryUnit` | `string` | HOUR, DAY, WEEK, MONTH, YEAR |
| `remoteStatus` | `string` | On-site, Remote, Hybrid |
| `validThrough` | `timestamp` | Application deadline |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
### `candidate`
A person who has applied or been added to the talent pool.
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `firstName` / `lastName` | `string` | Full name |
| `email` | `string` | Email (unique per org) |
| `phone` | `string` | Phone number |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
**Unique constraint**: `(organizationId, email)` — prevents duplicate candidates within an org.
### `application`
Links a candidate to a job with a pipeline status.
| Column | Type | Description |
|--------|------|-------------|
| `id` | `uuid` | Primary key |
| `organizationId` | `string` | FK → organization |
| `jobId` | `uuid` | FK → job |
| `candidateId` | `uuid` | FK → candidate |
| `status` | `enum` | `new`, `screening`, `interview`, `offer`, `hired`, `rejected` |
| `notes` | `text` | Application-specific notes |
| `score` | `integer` | Recruiter-assigned score |
| `coverLetterText` | `text` | Parsed/submitted cover letter text |
| `createdAt` / `updatedAt` | `timestamp` | Timestamps |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@content/docs/4.architecture/3.data-model.md` around lines 31 - 77, Update the
documented table definitions to match the actual schema: in the `job` table
replace `employmentType` with `type` and add the `requireResume` and
`requireCoverLetter` columns; in the `candidate` table either add the `notes`
column if present in schema or remove it from the docs to match `candidate`'s
actual columns; in the `application` table add `coverLetterText` to the column
list. Use the exact column identifiers (`type`, `requireResume`,
`requireCoverLetter`, `notes`, `coverLetterText`) and update the
descriptions/column types to mirror `server/database/schema/app.ts` so docs and
schema are consistent.

Comment on lines +65 to +71
```
server/api/jobs/index.get.ts → GET /api/jobs
server/api/jobs/index.post.ts → POST /api/jobs
server/api/jobs/[id].get.ts → GET /api/jobs/:id
server/api/jobs/[id].patch.ts → PATCH /api/jobs/:id
server/api/jobs/[id].delete.ts → DELETE /api/jobs/:id
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Specify a language for the route-mapping block.

This fenced block has no language tag, which triggers markdownlint MD040.

Suggested fix
-```
+```text
 server/api/jobs/index.get.ts     → GET /api/jobs
 ...
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @content/docs/5.contributing/2.coding-conventions.md around lines 65 - 71,
The fenced route-mapping block showing the API paths (the three backtick block
containing lines like "server/api/jobs/index.get.ts → GET /api/jobs" and the
other route mappings) lacks a language tag and triggers markdownlint MD040; fix
it by adding a language identifier (use "text") to the opening fence so the
block becomes ```text and the rest of the content remains unchanged.


</details>

<!-- fingerprinting:phantom:poseidon:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment thread nuxt.config.ts
Comment on lines 191 to 196
content: {
// content.config.ts handles collection definitions
highlight: {
theme: 'one-dark-pro',
},
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

@nuxt/content v3 module options configuration highlight

💡 Result:

In Nuxt Content v3, syntax highlighting is configured under:

  • content.build.markdown.highlight

highlight can be false (default) or an object with:

  • theme: a Shiki theme string, or an object of themes (supports Nuxt Color Mode; recommended to include default)
  • langs: an array of Shiki languages to preload (defaults include json, js, ts, html, css, vue, shell, mdc, md, yaml) [1]

Example (nuxt.config.ts):

export default defineNuxtConfig({
  content: {
    build: {
      markdown: {
        highlight: {
          theme: {
            default: 'github-light',
            dark: 'github-dark'
          },
          langs: ['json', 'ts', 'vue', 'bash', 'python']
        }
      }
    }
  }
})

Nuxt Content uses Shiki for highlighting (used by ProsePre / ProseCode) [1]. Shiki is provided via the MDC layer that Nuxt Content builds on [2].

Sources: [1] [2]


🌐 Web query:

@nuxt/content v3 syntax highlighting theme configuration

💡 Result:

In @nuxt/content v3, syntax highlighting is configured via content.highlight in nuxt.config.ts, and the theme is set with content.highlight.theme. It can be:

  • a single Shiki theme id (applies to all color schemes), or
  • an object of themes keyed by color-mode names (recommended to include default). [1]
// nuxt.config.ts
export default defineNuxtConfig({
  content: {
    highlight: {
      // single theme
      theme: 'github-light',

      // or per color-mode theme
      // theme: {
      //   default: 'github-light',
      //   dark: 'github-dark',
      //   sepia: 'monokai'
      // }
    }
  }
})

Pick any theme id bundled by Shiki (see the “Themes” list), or use none to bypass highlighting. [2]


🌐 Web query:

@nuxt/content ModuleOptions v3 API reference

💡 Result:

@nuxt/content v3 ModuleOptions (API reference)

Where the canonical options live

  • Docs (human-readable): Nuxt Content v3 configuration reference (this is what you set under content: in nuxt.config). [1]
  • Types (TypeScript source of truth): ModuleOptions is declared in the package’s generated types (e.g. dist/module.d.mts). [2]
    The package export also points the root types to ./dist/module.d.mts. [3]

How to use in Nuxt config

export default defineNuxtConfig({
  content: {
    // ModuleOptions here
  }
})

[1]

ModuleOptions (top-level shape, v3)

From the published type definition, ModuleOptions includes (at least) these top-level keys: [2]

  • database (prod database adapter/config)
  • preview (preview mode config)
  • watch (dev HMR / watcher config)
  • renderer (render-time options like alias, anchorLinks)
  • build (build-time parsing/markdown options like transformers, markdown toc, remarkPlugins, etc.)
  • pathMeta-related options (slug/path metadata behavior)

Full details for build/database/renderer/watch (including defaults and option types) are documented here: [1]

Sources: [1] [2] [3]


Move syntax highlighting configuration to content.build.markdown.highlight.

In @nuxt/content v3, the highlight option is no longer a top-level content module property. It must be nested under content.build.markdown.highlight. Update the configuration to:

content: {
  build: {
    markdown: {
      highlight: {
        theme: 'one-dark-pro',
      },
    },
  },
},
🧰 Tools
🪛 GitHub Actions: PR Validation

[error] 193-193: TypeScript error: Object literal may only specify known properties, and 'highlight' does not exist in type 'Partial'.

🪛 GitHub Check: Build, typecheck, and test

[failure] 193-193:
Object literal may only specify known properties, and 'highlight' does not exist in type 'Partial'.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@nuxt.config.ts` around lines 191 - 196, The current top-level
content.highlight setting must be moved under the build->markdown tree: remove
the existing content.highlight entry and add it as
content.build.markdown.highlight with the same theme value (i.e., move the
'highlight' object from the top-level 'content' config into
'content.build.markdown.highlight'); update the 'content' object in nuxt config
so the 'highlight' key lives at content.build.markdown.highlight (preserving
theme: 'one-dark-pro').

Signed-off-by: Joachim <joachim.l.kolle.pers@gmail.com>
@railway-app railway-app Bot temporarily deployed to applirank / reqcore-pr-69 March 5, 2026 12:13 Destroyed
@railway-app railway-app Bot temporarily deployed to applirank / reqcore-pr-69 March 5, 2026 16:21 Destroyed
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
app/pages/docs/[...slug].vue (2)

84-90: Consider centralizing section-to-icon mappings.

The sectionIcons mapping here (5 entries) differs from the iconMap in app/pages/docs/index.vue (19 entries with different keys). Both files independently define icon mappings, which could lead to maintenance drift.

Consider extracting a shared docs-config.ts utility:

// app/utils/docs-config.ts
import { Rocket, Container, Briefcase, Layers, Code, BookOpen } from 'lucide-vue-next'
import type { LucideIcon } from 'lucide-vue-next'

export const sectionIcons: Record<string, LucideIcon> = {
  'Getting Started': Rocket,
  'Deployment': Container,
  'Features': Briefcase,
  'Architecture': Layers,
  'Contributing': Code,
}

export const defaultIcon = BookOpen
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/docs/`[...slug].vue around lines 84 - 90, The section-to-icon
mapping is duplicated between sectionIcons and iconMap; extract a shared mapping
and default icon into a new module (e.g., docs-config) and import it where
needed: move the current sectionIcons object into the new module, add a
defaultIcon (e.g., BookOpen), and update both the sectionIcons reference in the
component that defines sectionIcons and the iconMap user in the other component
to import the shared sectionIcons and defaultIcon; ensure all references to
sectionIcons and iconMap keys align (rename or merge keys as needed) so
components use the single canonical mapping.

104-108: Consider adding fallbacks for defensive robustness, though current docs are well-formed.

Verification confirms all 19 docs in content/docs/ have title fields defined, and doc.path is auto-generated by Nuxt Content. The non-null assertions are currently safe. However, adding fallback values would improve resilience against edge cases and makes the code more defensive:

     grouped[section].push({
-      path: doc.path!,
-      title: doc.title!,
+      path: doc.path ?? '',
+      title: doc.title ?? 'Untitled',
       active: doc.path === slugPath.value,
     })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/docs/`[...slug].vue around lines 104 - 108, The code uses non-null
assertions for doc.path and doc.title when pushing into grouped[section];
replace these with safe fallbacks to avoid runtime errors: use a fallback path
like doc.path ?? '' (or String(doc.path ?? '')) and a fallback title like
doc.title ?? 'Untitled' (or similar), and compute active by comparing (doc.path
?? '') to slugPath.value to ensure the comparison won't fail if path is
undefined; update the push in the grouped[section] block and any related logic
that reads doc.path/doc.title to use these fallbacks.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@app/pages/docs/`[...slug].vue:
- Around line 84-90: The section-to-icon mapping is duplicated between
sectionIcons and iconMap; extract a shared mapping and default icon into a new
module (e.g., docs-config) and import it where needed: move the current
sectionIcons object into the new module, add a defaultIcon (e.g., BookOpen), and
update both the sectionIcons reference in the component that defines
sectionIcons and the iconMap user in the other component to import the shared
sectionIcons and defaultIcon; ensure all references to sectionIcons and iconMap
keys align (rename or merge keys as needed) so components use the single
canonical mapping.
- Around line 104-108: The code uses non-null assertions for doc.path and
doc.title when pushing into grouped[section]; replace these with safe fallbacks
to avoid runtime errors: use a fallback path like doc.path ?? '' (or
String(doc.path ?? '')) and a fallback title like doc.title ?? 'Untitled' (or
similar), and compute active by comparing (doc.path ?? '') to slugPath.value to
ensure the comparison won't fail if path is undefined; update the push in the
grouped[section] block and any related logic that reads doc.path/doc.title to
use these fallbacks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 07fbdfee-7cfe-4627-8a60-09f6bf0be368

📥 Commits

Reviewing files that changed from the base of the PR and between 625113a and 6731ae9.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (9)
  • .github/workflows/allure-pages.yml
  • .github/workflows/e2e-tests.yml
  • .gitignore
  • .npmrc
  • allurerc.mjs
  • app/pages/docs/[...slug].vue
  • nuxt.config.ts
  • package.json
  • playwright.config.ts
💤 Files with no reviewable changes (4)
  • playwright.config.ts
  • .github/workflows/allure-pages.yml
  • .github/workflows/e2e-tests.yml
  • allurerc.mjs

@JoachimLK JoachimLK merged commit 2b05075 into main Mar 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant