Help CenterContributingCoding Conventions

Coding Conventions

Code style, naming patterns, and best practices for Reqcore development. Covers Vue components, API routes, Drizzle queries, and more.

Coding Conventions

This guide covers the coding standards and patterns used throughout Reqcore. Following these conventions ensures consistency and prevents common mistakes.

TypeScript

Reqcore is fully typed. Nuxt 4 provides separate TypeScript contexts for app/ and server/:

  • Server utilities are not available in app/ code (and vice versa)
  • Use shared/ for types and functions needed in both contexts
  • API response types are inferred automatically by useFetch

Vue Components

File Organization

<script setup lang="ts">
// 1. Imports (framework, libraries, types)
import { Briefcase, ArrowRight } from 'lucide-vue-next'

// 2. Page meta & SEO
definePageMeta({ layout: 'dashboard', middleware: ['auth'] })
useSeoMeta({ title: 'Jobs', description: '...' })

// 3. Reactive state & composables
const { data: jobs } = await useFetch('/api/jobs', {
  headers: useRequestHeaders(['cookie']),
})

// 4. Computed properties
const openJobs = computed(() =>
  jobs.value?.filter(j => j.status === 'open') ?? []
)

// 5. Methods
function handleCreate() { /* ... */ }
</script>

<template>
  <!-- Component template -->
</template>

Naming

ItemConventionExample
ComponentsPascalCasePipelineCard.vue, OrgSwitcher.vue
ComposablescamelCase with use prefixuseJobs(), useCandidate()
Pageskebab-caseapplication-form.vue
Layoutskebab-casedashboard.vue

API Routes

File Naming

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

Handler Pattern

export default defineEventHandler(async (event) => {
  // 1. Authenticate
  const { session } = await requireAuth(event)
  const orgId = session.activeOrganizationId

  // 2. Validate input
  const body = await readValidatedBody(event, schema.parse)

  // 3. Query (always scoped by orgId)
  const result = await db
    .select()
    .from(table)
    .where(eq(table.organizationId, orgId))

  // 4. Return data
  return result
})

Error Handling

// ✅ Correct — throws proper HTTP error
throw createError({ statusCode: 404, message: 'Job not found' })

// ❌ Wrong — returns 200 with error body
return { error: 'Job not found' }

Database Queries

Always Scope by Organization

// ✅ Every query MUST include organizationId
const jobs = await db
  .select()
  .from(job)
  .where(eq(job.organizationId, orgId))

// ❌ Never query without org scope
const jobs = await db.select().from(job)

Use Drizzle Operators

import { eq, and, desc } from 'drizzle-orm'

const results = await db
  .select()
  .from(application)
  .where(
    and(
      eq(application.organizationId, orgId),
      eq(application.jobId, jobId),
    )
  )
  .orderBy(desc(application.createdAt))

CSS & Styling

Tailwind CSS v4

  • Use utility classes — avoid custom CSS
  • Theme tokens are defined in app/assets/css/main.css via @theme
  • The brand-* color scale maps to the primary color

Dark Theme Pages

Public pages (landing, blog, roadmap, docs) use a dark theme:

useHead({
  bodyAttrs: {
    style: 'background-color: #09090b;',
  },
})

Common dark theme patterns:

  • Background: bg-[#09090b]
  • Text: text-white, text-white/50, text-white/40
  • Borders: border-white/[0.06]
  • Cards: bg-white/[0.02], hover: bg-white/[0.04]
  • Glow: blur-[120px] with brand colors

Environment Variables

// ✅ Use the validated env utility
import { env } from '~/server/utils/env'
const dbUrl = env.DATABASE_URL

// ❌ Never access process.env directly in server code
const dbUrl = process.env.DATABASE_URL

Next Steps

  • Development Setup — Get your environment ready
  • Preserve tenant isolation and authenticated server access when changing shared behavior
\n\n\n","vue","",[28,81,82,112,119,135,142,148,169,190,195,201,241,259,265,270,276,296,331,337,342,348,366,376,381,391,397],{"__ignoreMap":79},[83,84,87,91,95,99,102,105,109],"span",{"class":85,"line":86},"line",1,[83,88,90],{"class":89},"sVt8B","<",[83,92,94],{"class":93},"s9eBZ","script",[83,96,98],{"class":97},"sScJk"," setup",[83,100,101],{"class":97}," lang",[83,103,104],{"class":89},"=",[83,106,108],{"class":107},"sZZnC","\"ts\"",[83,110,111],{"class":89},">\n",[83,113,115],{"class":85,"line":114},2,[83,116,118],{"class":117},"sJ8bj","// 1. Imports (framework, libraries, types)\n",[83,120,122,126,129,132],{"class":85,"line":121},3,[83,123,125],{"class":124},"szBVR","import",[83,127,128],{"class":89}," { Briefcase, ArrowRight } ",[83,130,131],{"class":124},"from",[83,133,134],{"class":107}," 'lucide-vue-next'\n",[83,136,138],{"class":85,"line":137},4,[83,139,141],{"emptyLinePlaceholder":140},true,"\n",[83,143,145],{"class":85,"line":144},5,[83,146,147],{"class":117},"// 2. Page meta & SEO\n",[83,149,151,154,157,160,163,166],{"class":85,"line":150},6,[83,152,153],{"class":97},"definePageMeta",[83,155,156],{"class":89},"({ layout: ",[83,158,159],{"class":107},"'dashboard'",[83,161,162],{"class":89},", middleware: [",[83,164,165],{"class":107},"'auth'",[83,167,168],{"class":89},"] })\n",[83,170,172,175,178,181,184,187],{"class":85,"line":171},7,[83,173,174],{"class":97},"useSeoMeta",[83,176,177],{"class":89},"({ title: ",[83,179,180],{"class":107},"'Jobs'",[83,182,183],{"class":89},", description: ",[83,185,186],{"class":107},"'...'",[83,188,189],{"class":89}," })\n",[83,191,193],{"class":85,"line":192},8,[83,194,141],{"emptyLinePlaceholder":140},[83,196,198],{"class":85,"line":197},9,[83,199,200],{"class":117},"// 3. Reactive state & composables\n",[83,202,204,207,210,214,217,221,224,226,229,232,235,238],{"class":85,"line":203},10,[83,205,206],{"class":124},"const",[83,208,209],{"class":89}," { ",[83,211,213],{"class":212},"s4XuR","data",[83,215,216],{"class":89},": ",[83,218,220],{"class":219},"sj4cs","jobs",[83,222,223],{"class":89}," } ",[83,225,104],{"class":124},[83,227,228],{"class":124}," await",[83,230,231],{"class":97}," useFetch",[83,233,234],{"class":89},"(",[83,236,237],{"class":107},"'/api/jobs'",[83,239,240],{"class":89},", {\n",[83,242,244,247,250,253,256],{"class":85,"line":243},11,[83,245,246],{"class":89}," headers: ",[83,248,249],{"class":97},"useRequestHeaders",[83,251,252],{"class":89},"([",[83,254,255],{"class":107},"'cookie'",[83,257,258],{"class":89},"]),\n",[83,260,262],{"class":85,"line":261},12,[83,263,264],{"class":89},"})\n",[83,266,268],{"class":85,"line":267},13,[83,269,141],{"emptyLinePlaceholder":140},[83,271,273],{"class":85,"line":272},14,[83,274,275],{"class":117},"// 4. Computed properties\n",[83,277,279,281,284,287,290,293],{"class":85,"line":278},15,[83,280,206],{"class":124},[83,282,283],{"class":219}," openJobs",[83,285,286],{"class":124}," =",[83,288,289],{"class":97}," computed",[83,291,292],{"class":89},"(() ",[83,294,295],{"class":124},"=>\n",[83,297,299,302,305,307,310,313,316,319,322,325,328],{"class":85,"line":298},16,[83,300,301],{"class":89}," jobs.value?.",[83,303,304],{"class":97},"filter",[83,306,234],{"class":89},[83,308,309],{"class":212},"j",[83,311,312],{"class":124}," =>",[83,314,315],{"class":89}," j.status ",[83,317,318],{"class":124},"===",[83,320,321],{"class":107}," 'open'",[83,323,324],{"class":89},") ",[83,326,327],{"class":124},"??",[83,329,330],{"class":89}," []\n",[83,332,334],{"class":85,"line":333},17,[83,335,336],{"class":89},")\n",[83,338,340],{"class":85,"line":339},18,[83,341,141],{"emptyLinePlaceholder":140},[83,343,345],{"class":85,"line":344},19,[83,346,347],{"class":117},"// 5. Methods\n",[83,349,351,354,357,360,363],{"class":85,"line":350},20,[83,352,353],{"class":124},"function",[83,355,356],{"class":97}," handleCreate",[83,358,359],{"class":89},"() { ",[83,361,362],{"class":117},"/* ... */",[83,364,365],{"class":89}," }\n",[83,367,369,372,374],{"class":85,"line":368},21,[83,370,371],{"class":89},"\n",[83,398,400,402,404],{"class":85,"line":399},25,[83,401,371],{"class":89},[83,403,388],{"class":93},[83,405,111],{"class":89},[69,407,409],{"id":408},"naming","Naming",[411,412,413,429],"table",{},[414,415,416],"thead",{},[417,418,419,423,426],"tr",{},[420,421,422],"th",{},"Item",[420,424,425],{},"Convention",[420,427,428],{},"Example",[430,431,432,450,470,483],"tbody",{},[417,433,434,438,441],{},[435,436,437],"td",{},"Components",[435,439,440],{},"PascalCase",[435,442,443,446,447],{},[28,444,445],{},"PipelineCard.vue",", ",[28,448,449],{},"OrgSwitcher.vue",[417,451,452,455,462],{},[435,453,454],{},"Composables",[435,456,457,458,461],{},"camelCase with ",[28,459,460],{},"use"," prefix",[435,463,464,446,467],{},[28,465,466],{},"useJobs()",[28,468,469],{},"useCandidate()",[417,471,472,475,478],{},[435,473,474],{},"Pages",[435,476,477],{},"kebab-case",[435,479,480],{},[28,481,482],{},"application-form.vue",[417,484,485,488,490],{},[435,486,487],{},"Layouts",[435,489,477],{},[435,491,492],{},[28,493,494],{},"dashboard.vue",[20,496,498],{"id":497},"api-routes","API Routes",[69,500,502],{"id":501},"file-naming","File Naming",[74,504,509],{"className":505,"code":507,"language":508},[506],"language-text","server/api/jobs/index.get.ts → GET /api/jobs\nserver/api/jobs/index.post.ts → POST /api/jobs\nserver/api/jobs/[id].get.ts → GET /api/jobs/:id\nserver/api/jobs/[id].patch.ts → PATCH /api/jobs/:id\nserver/api/jobs/[id].delete.ts → DELETE /api/jobs/:id\n","text",[28,510,507],{"__ignoreMap":79},[69,512,514],{"id":513},"handler-pattern","Handler Pattern",[74,516,520],{"className":517,"code":518,"language":519,"meta":79,"style":79},"language-ts shiki shiki-themes github-light github-dark","export default defineEventHandler(async (event) => {\n // 1. Authenticate\n const { session } = await requireAuth(event)\n const orgId = session.activeOrganizationId\n\n // 2. Validate input\n const body = await readValidatedBody(event, schema.parse)\n\n // 3. Query (always scoped by orgId)\n const result = await db\n .select()\n .from(table)\n .where(eq(table.organizationId, orgId))\n\n // 4. Return data\n return result\n})\n","ts",[28,521,522,552,557,579,591,595,600,617,621,626,640,651,660,675,679,684,692],{"__ignoreMap":79},[83,523,524,527,530,533,535,538,541,544,546,549],{"class":85,"line":86},[83,525,526],{"class":124},"export",[83,528,529],{"class":124}," default",[83,531,532],{"class":97}," defineEventHandler",[83,534,234],{"class":89},[83,536,537],{"class":124},"async",[83,539,540],{"class":89}," (",[83,542,543],{"class":212},"event",[83,545,324],{"class":89},[83,547,548],{"class":124},"=>",[83,550,551],{"class":89}," {\n",[83,553,554],{"class":85,"line":114},[83,555,556],{"class":117}," // 1. Authenticate\n",[83,558,559,562,564,567,569,571,573,576],{"class":85,"line":121},[83,560,561],{"class":124}," const",[83,563,209],{"class":89},[83,565,566],{"class":219},"session",[83,568,223],{"class":89},[83,570,104],{"class":124},[83,572,228],{"class":124},[83,574,575],{"class":97}," requireAuth",[83,577,578],{"class":89},"(event)\n",[83,580,581,583,586,588],{"class":85,"line":137},[83,582,561],{"class":124},[83,584,585],{"class":219}," orgId",[83,587,286],{"class":124},[83,589,590],{"class":89}," session.activeOrganizationId\n",[83,592,593],{"class":85,"line":144},[83,594,141],{"emptyLinePlaceholder":140},[83,596,597],{"class":85,"line":150},[83,598,599],{"class":117}," // 2. Validate input\n",[83,601,602,604,607,609,611,614],{"class":85,"line":171},[83,603,561],{"class":124},[83,605,606],{"class":219}," body",[83,608,286],{"class":124},[83,610,228],{"class":124},[83,612,613],{"class":97}," readValidatedBody",[83,615,616],{"class":89},"(event, schema.parse)\n",[83,618,619],{"class":85,"line":192},[83,620,141],{"emptyLinePlaceholder":140},[83,622,623],{"class":85,"line":197},[83,624,625],{"class":117}," // 3. Query (always scoped by orgId)\n",[83,627,628,630,633,635,637],{"class":85,"line":203},[83,629,561],{"class":124},[83,631,632],{"class":219}," result",[83,634,286],{"class":124},[83,636,228],{"class":124},[83,638,639],{"class":89}," db\n",[83,641,642,645,648],{"class":85,"line":243},[83,643,644],{"class":89}," .",[83,646,647],{"class":97},"select",[83,649,650],{"class":89},"()\n",[83,652,653,655,657],{"class":85,"line":261},[83,654,644],{"class":89},[83,656,131],{"class":97},[83,658,659],{"class":89},"(table)\n",[83,661,662,664,667,669,672],{"class":85,"line":267},[83,663,644],{"class":89},[83,665,666],{"class":97},"where",[83,668,234],{"class":89},[83,670,671],{"class":97},"eq",[83,673,674],{"class":89},"(table.organizationId, orgId))\n",[83,676,677],{"class":85,"line":272},[83,678,141],{"emptyLinePlaceholder":140},[83,680,681],{"class":85,"line":278},[83,682,683],{"class":117}," // 4. Return data\n",[83,685,686,689],{"class":85,"line":298},[83,687,688],{"class":124}," return",[83,690,691],{"class":89}," result\n",[83,693,694],{"class":85,"line":333},[83,695,264],{"class":89},[69,697,699],{"id":698},"error-handling","Error Handling",[74,701,703],{"className":517,"code":702,"language":519,"meta":79,"style":79},"// ✅ Correct — throws proper HTTP error\nthrow createError({ statusCode: 404, message: 'Job not found' })\n\n// ❌ Wrong — returns 200 with error body\nreturn { error: 'Job not found' }\n",[28,704,705,710,732,736,741],{"__ignoreMap":79},[83,706,707],{"class":85,"line":86},[83,708,709],{"class":117},"// ✅ Correct — throws proper HTTP error\n",[83,711,712,715,718,721,724,727,730],{"class":85,"line":114},[83,713,714],{"class":124},"throw",[83,716,717],{"class":97}," createError",[83,719,720],{"class":89},"({ statusCode: ",[83,722,723],{"class":219},"404",[83,725,726],{"class":89},", message: ",[83,728,729],{"class":107},"'Job not found'",[83,731,189],{"class":89},[83,733,734],{"class":85,"line":121},[83,735,141],{"emptyLinePlaceholder":140},[83,737,738],{"class":85,"line":137},[83,739,740],{"class":117},"// ❌ Wrong — returns 200 with error body\n",[83,742,743,746,749,751],{"class":85,"line":144},[83,744,745],{"class":124},"return",[83,747,748],{"class":89}," { error: ",[83,750,729],{"class":107},[83,752,365],{"class":89},[20,754,756],{"id":755},"database-queries","Database Queries",[69,758,760],{"id":759},"always-scope-by-organization","Always Scope by Organization",[74,762,764],{"className":517,"code":763,"language":519,"meta":79,"style":79},"// ✅ Every query MUST include organizationId\nconst jobs = await db\n .select()\n .from(job)\n .where(eq(job.organizationId, orgId))\n\n// ❌ Never query without org scope\nconst jobs = await db.select().from(job)\n",[28,765,766,771,784,793,802,815,819,824],{"__ignoreMap":79},[83,767,768],{"class":85,"line":86},[83,769,770],{"class":117},"// ✅ Every query MUST include organizationId\n",[83,772,773,775,778,780,782],{"class":85,"line":114},[83,774,206],{"class":124},[83,776,777],{"class":219}," jobs",[83,779,286],{"class":124},[83,781,228],{"class":124},[83,783,639],{"class":89},[83,785,786,789,791],{"class":85,"line":121},[83,787,788],{"class":89}," .",[83,790,647],{"class":97},[83,792,650],{"class":89},[83,794,795,797,799],{"class":85,"line":137},[83,796,788],{"class":89},[83,798,131],{"class":97},[83,800,801],{"class":89},"(job)\n",[83,803,804,806,808,810,812],{"class":85,"line":144},[83,805,788],{"class":89},[83,807,666],{"class":97},[83,809,234],{"class":89},[83,811,671],{"class":97},[83,813,814],{"class":89},"(job.organizationId, orgId))\n",[83,816,817],{"class":85,"line":150},[83,818,141],{"emptyLinePlaceholder":140},[83,820,821],{"class":85,"line":171},[83,822,823],{"class":117},"// ❌ Never query without org scope\n",[83,825,826,828,830,832,834,837,839,842,844],{"class":85,"line":192},[83,827,206],{"class":124},[83,829,777],{"class":219},[83,831,286],{"class":124},[83,833,228],{"class":124},[83,835,836],{"class":89}," db.",[83,838,647],{"class":97},[83,840,841],{"class":89},"().",[83,843,131],{"class":97},[83,845,801],{"class":89},[69,847,849],{"id":848},"use-drizzle-operators","Use Drizzle Operators",[74,851,853],{"className":517,"code":852,"language":519,"meta":79,"style":79},"import { eq, and, desc } from 'drizzle-orm'\n\nconst results = await db\n .select()\n .from(application)\n .where(\n and(\n eq(application.organizationId, orgId),\n eq(application.jobId, jobId),\n )\n )\n .orderBy(desc(application.createdAt))\n",[28,854,855,867,871,884,892,901,910,917,925,932,937,942],{"__ignoreMap":79},[83,856,857,859,862,864],{"class":85,"line":86},[83,858,125],{"class":124},[83,860,861],{"class":89}," { eq, and, desc } ",[83,863,131],{"class":124},[83,865,866],{"class":107}," 'drizzle-orm'\n",[83,868,869],{"class":85,"line":114},[83,870,141],{"emptyLinePlaceholder":140},[83,872,873,875,878,880,882],{"class":85,"line":121},[83,874,206],{"class":124},[83,876,877],{"class":219}," results",[83,879,286],{"class":124},[83,881,228],{"class":124},[83,883,639],{"class":89},[83,885,886,888,890],{"class":85,"line":137},[83,887,788],{"class":89},[83,889,647],{"class":97},[83,891,650],{"class":89},[83,893,894,896,898],{"class":85,"line":144},[83,895,788],{"class":89},[83,897,131],{"class":97},[83,899,900],{"class":89},"(application)\n",[83,902,903,905,907],{"class":85,"line":150},[83,904,788],{"class":89},[83,906,666],{"class":97},[83,908,909],{"class":89},"(\n",[83,911,912,915],{"class":85,"line":171},[83,913,914],{"class":97}," and",[83,916,909],{"class":89},[83,918,919,922],{"class":85,"line":192},[83,920,921],{"class":97}," eq",[83,923,924],{"class":89},"(application.organizationId, orgId),\n",[83,926,927,929],{"class":85,"line":197},[83,928,921],{"class":97},[83,930,931],{"class":89},"(application.jobId, jobId),\n",[83,933,934],{"class":85,"line":203},[83,935,936],{"class":89}," )\n",[83,938,939],{"class":85,"line":243},[83,940,941],{"class":89}," )\n",[83,943,944,946,949,951,954],{"class":85,"line":261},[83,945,788],{"class":89},[83,947,948],{"class":97},"orderBy",[83,950,234],{"class":89},[83,952,953],{"class":97},"desc",[83,955,956],{"class":89},"(application.createdAt))\n",[20,958,960],{"id":959},"css-styling","CSS & Styling",[69,962,964],{"id":963},"tailwind-css-v4","Tailwind CSS v4",[37,966,967,970,980],{},[40,968,969],{},"Use utility classes — avoid custom CSS",[40,971,972,973,976,977],{},"Theme tokens are defined in ",[28,974,975],{},"app/assets/css/main.css"," via ",[28,978,979],{},"@theme",[40,981,982,983,986],{},"The ",[28,984,985],{},"brand-*"," color scale maps to the primary color",[69,988,990],{"id":989},"dark-theme-pages","Dark Theme Pages",[16,992,993],{},"Public pages (landing, blog, roadmap, docs) use a dark theme:",[74,995,997],{"className":76,"code":996,"language":78,"meta":79,"style":79},"useHead({\n bodyAttrs: {\n style: 'background-color: #09090b;',\n },\n})\n",[28,998,999,1004,1009,1014,1019],{"__ignoreMap":79},[83,1000,1001],{"class":85,"line":86},[83,1002,1003],{"class":89},"useHead({\n",[83,1005,1006],{"class":85,"line":114},[83,1007,1008],{"class":89}," bodyAttrs: {\n",[83,1010,1011],{"class":85,"line":121},[83,1012,1013],{"class":89}," style: 'background-color: #09090b;',\n",[83,1015,1016],{"class":85,"line":137},[83,1017,1018],{"class":89}," },\n",[83,1020,1021],{"class":85,"line":144},[83,1022,264],{"class":89},[16,1024,1025],{},"Common dark theme patterns:",[37,1027,1028,1034,1046,1052,1062],{},[40,1029,1030,1031],{},"Background: ",[28,1032,1033],{},"bg-[#09090b]",[40,1035,1036,1037,446,1040,446,1043],{},"Text: ",[28,1038,1039],{},"text-white",[28,1041,1042],{},"text-white/50",[28,1044,1045],{},"text-white/40",[40,1047,1048,1049],{},"Borders: ",[28,1050,1051],{},"border-white/[0.06]",[40,1053,1054,1055,1058,1059],{},"Cards: ",[28,1056,1057],{},"bg-white/[0.02]",", hover: ",[28,1060,1061],{},"bg-white/[0.04]",[40,1063,1064,1065,1068],{},"Glow: ",[28,1066,1067],{},"blur-[120px]"," with brand colors",[20,1070,1072],{"id":1071},"environment-variables","Environment Variables",[74,1074,1076],{"className":517,"code":1075,"language":519,"meta":79,"style":79},"// ✅ Use the validated env utility\nimport { env } from '~/server/utils/env'\nconst dbUrl = env.DATABASE_URL\n\n// ❌ Never access process.env directly in server code\nconst dbUrl = process.env.DATABASE_URL\n",[28,1077,1078,1083,1095,1110,1114,1119],{"__ignoreMap":79},[83,1079,1080],{"class":85,"line":86},[83,1081,1082],{"class":117},"// ✅ Use the validated env utility\n",[83,1084,1085,1087,1090,1092],{"class":85,"line":114},[83,1086,125],{"class":124},[83,1088,1089],{"class":89}," { env } ",[83,1091,131],{"class":124},[83,1093,1094],{"class":107}," '~/server/utils/env'\n",[83,1096,1097,1099,1102,1104,1107],{"class":85,"line":121},[83,1098,206],{"class":124},[83,1100,1101],{"class":219}," dbUrl",[83,1103,286],{"class":124},[83,1105,1106],{"class":89}," env.",[83,1108,1109],{"class":219},"DATABASE_URL\n",[83,1111,1112],{"class":85,"line":137},[83,1113,141],{"emptyLinePlaceholder":140},[83,1115,1116],{"class":85,"line":144},[83,1117,1118],{"class":117},"// ❌ Never access process.env directly in server code\n",[83,1120,1121,1123,1125,1127,1130],{"class":85,"line":150},[83,1122,206],{"class":124},[83,1124,1101],{"class":219},[83,1126,286],{"class":124},[83,1128,1129],{"class":89}," process.env.",[83,1131,1109],{"class":219},[20,1133,1135],{"id":1134},"next-steps","Next Steps",[37,1137,1138,1146],{},[40,1139,1140,1145],{},[1141,1142,1144],"a",{"href":1143},"/docs/contributing/development-setup","Development Setup"," — Get your environment ready",[40,1147,1148],{},"Preserve tenant isolation and authenticated server access when changing shared behavior",[1150,1151,1152],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s9eBZ, html code.shiki .s9eBZ{--shiki-default:#22863A;--shiki-dark:#85E89D}",{"title":79,"searchDepth":114,"depth":114,"links":1154},[1155,1156,1160,1165,1169,1173,1174],{"id":22,"depth":114,"text":23},{"id":66,"depth":114,"text":67,"children":1157},[1158,1159],{"id":71,"depth":121,"text":72},{"id":408,"depth":121,"text":409},{"id":497,"depth":114,"text":498,"children":1161},[1162,1163,1164],{"id":501,"depth":121,"text":502},{"id":513,"depth":121,"text":514},{"id":698,"depth":121,"text":699},{"id":755,"depth":114,"text":756,"children":1166},[1167,1168],{"id":759,"depth":121,"text":760},{"id":848,"depth":121,"text":849},{"id":959,"depth":114,"text":960,"children":1170},[1171,1172],{"id":963,"depth":121,"text":964},{"id":989,"depth":121,"text":990},{"id":1071,"depth":114,"text":1072},{"id":1134,"depth":114,"text":1135},"Code style, naming patterns, and best practices for Reqcore development. Covers Vue components, API routes, Drizzle queries, and more.","md","file-code",{},"/docs/contributing/coding-conventions","Contributing",{"title":7,"description":1175},"docs/5.contributing/2.coding-conventions","xfr7NdUxzor-uCSSsbK2LLbyoLnmoxVJPPqW8rbAVEA",[1185,1186,1187,1191,1194,1197,1200,1203,1206,1209,1213],{"path":1179,"title":7,"section":1180},{"path":1143,"title":1144,"section":1180},{"path":1188,"title":1189,"section":1190},"/docs/features/application-forms","Application Forms","Features",{"path":1192,"title":1193,"section":1190},"/docs/features/candidate-pipeline","Candidate Pipeline",{"path":1195,"title":1196,"section":1190},"/docs/features/dashboard","Dashboard",{"path":1198,"title":1199,"section":1190},"/docs/features/document-storage","Document Storage",{"path":1201,"title":1202,"section":1190},"/docs/features/google-calendar","Google Calendar Integration",{"path":1204,"title":1205,"section":1190},"/docs/features/job-management","Job Management",{"path":1207,"title":1208,"section":1190},"/docs/features/public-job-board","Public Job Board",{"path":1210,"title":1211,"section":1212},"/docs/getting-started/introduction","Introduction","Getting Started",{"path":1214,"title":1215,"section":1216},"/docs/legal/privacy-policy","Privacy Policy","Legal",["Reactive",1218],{"$snuxt-delay-hydration-mode":1219,"$si18n:cached-locale-configs":1220,"$si18n:resolved-locale":79,"$snuxt-seo-utils:routeRules":1235,"$ssite-config":1236},"mount",{"en":1221,"es":1223,"fr":1225,"de":1227,"nb":1229,"vi":1231,"ja":1233},{"fallbacks":1222,"cacheable":140},[],{"fallbacks":1224,"cacheable":140},[],{"fallbacks":1226,"cacheable":140},[],{"fallbacks":1228,"cacheable":140},[],{"fallbacks":1230,"cacheable":140},[],{"fallbacks":1232,"cacheable":140},[],{"fallbacks":1234,"cacheable":140},[],{"head":-1,"seoMeta":-1},{"_priority":1237,"currentLocale":1241,"defaultLocale":1241,"description":1242,"env":1243,"name":1244,"trailingSlash":1245,"url":1246},{"env":1238,"url":1239,"name":1240,"description":1240,"defaultLocale":1239,"trailingSlash":1240,"currentLocale":1239},-15,-2,-3,"en-US","Reqcore is the applicant tracking system that reads, screens, and shortlists your applicants automatically — so small businesses can hire great people without a recruiter. Flat pricing, unlimited users, live in minutes.","production","Reqcore",false,"https://reqcore.com",["Set"],["ShallowReactive",1249],{"docs-/docs/contributing/coding-conventions":-1,"docs-sidebar":-1}]