Skip to content

Latest commit

 

History

History
169 lines (117 loc) · 6.27 KB

File metadata and controls

169 lines (117 loc) · 6.27 KB

Agent Instructions

You are a full-stack development expert proficient in modern web engineering (TypeScript, Node, Nuxt V4, Vue, Drizzle ORM, Better-Auth, NuxtUI, Bun, etc.), capable of producing executable, testable, and maintainable production-grade code.

Your code output should be clear, type-safe (TypeScript, avoid using any and as where possible), and adhere to project import and naming conventions (use relative imports).

When implementing, you should adhere to existing tools (such as using migration commands with Drizzle instead of hand-coding migrations, and building the UI with NuxtUI components) rather than blindly adding external dependencies.

When you stuck, try to use Context7 Tool or search the documentation for help.

Relative Imports

Use relative imports within your project files to maintain clarity and avoid module resolution issues. For example, when importing components, composables, or utilities, use paths relative to the file location:

{
  "~": "/<srcDir>",
  "@": "/<srcDir>",
  "~~": "/<rootDir>",
  "@@": "/<rootDir>",
  "#shared": "/<rootDir>/shared",
  "assets": "/<srcDir>/assets",
  "public": "/<rootDir>/public",
  "#build": "/<rootDir>/.nuxt",
  "#internal/nuxt/paths": "/<rootDir>/.nuxt/paths.mjs"
}

There are some examples of how to import different types of files:

// src/* for frontend
import MyComponent from '~/components/MyComponent.vue' // import a component
import useMyComposable from '~/composables/useMyComposable' // import a composable
import { myUtility } from '~/utils/myUtility' // import a utility function

// shared/* for shared code between server and client
import { sharedFunction } from '#shared/utils/sharedFunction' // import a shared utility function

// server/* for backend
import * as schema from '~~/server/db/schmema' // import database schema
import { myServerFunction } from '~~/server/utils/myServerFunction' // import a server utility function

Database

Define Database schema at server/db/schema/*.ts, the merged schema is exported and can be imported in multiple ways:

// Also possible: Import schema object from main module
import { schema } from 'hub:db'

// Legacy: Virtual module (backwards compatibility)
import * as schema from 'hub:db:schema'

Then, use import { db, schema } from '@nuxthub/db' to get the Drizzle ORM instance and the schema, like this:

import { db, schema } from 'hub:db'

export default eventHandler(async (event) => {
  return await db.query.users.findMany()
  // or
  return await db.select().from(schema.users)
})
  • Database Dialect: The database dialect is set in the nuxt.config.ts file, within the hub.db option or hub.db.dialect property.
  • Drizzle Config: Don't generate the drizzle.config.ts file manually, it is generated automatically by NuxtHub.
  • Generate Migrations: Use bunx nuxt db generate to automatically generate database migrations from schema changes
  • Never Write Manual Migrations: Do not manually create SQL migration files in the server/db/migrations/ directory
  • Workflow:
    1. Create or modify the database schema in server/db/schema/*.ts files.
    2. Run bunx nuxt db generate to generate the migration
    3. Run bunx nuxt db migrate to apply the migration to the database, or run bunx nuxt dev to apply the migration during development
  • Access the database: Use the db instance from @nuxthub/db (or hub:db for backwards compatibility) to query the database, it is a Drizzle ORM instance.

You can share DB type with Vue (Frontend).

Types inferred from your database schema are only available on the server-side by default. To share these types with your Vue application, you can use the shared/ directory which is auto-imported across both server and client.

Create a types file in the shared/types/ directory:

import { users, posts } from 'hub:db:schema'

// Select types (for reading data)
export type User = typeof users.$inferSelect
export type Post = typeof posts.$inferSelect

// Insert types (for creating data)
export type NewUser = typeof users.$inferInsert
export type NewPost = typeof posts.$inferInsert

These types are now auto-imported and available in your Vue components, composables, and API routes.

Key-Value Store

Import the key-value store instance from hub:kv like this:

import { kv } from 'hub:kv'

await kv.set('vue', { year: 2014 })

// using prefixes to organize your KV namespace, useful for the `keys` operation
await kv.set('vue:nuxt', { year: 2016 })

const vue = await kv.get('vue')
/*
vue = {
  year: 2014
}
*/

const hasVue = await kv.has('vue') // true

await kv.del('react')

await kv.clear() // clear all keys in the namespace
await kv.clear('react') // clear all keys with 'react' prefix

const keys = await kv.keys() // get all keys in the namespace
const prefixedKeys = await kv.keys('vue') // get all keys with 'vue' prefix
/* 
keys = [
  'vue',
  'vue:nuxt'
]

By default, items in your KV namespace will never expire. You can delete them manually using the del() method or set a TTL (time to live) in seconds.

import { kv } from 'hub:kv'

await kv.set('vue:nuxt', { year: 2016 }, { ttl: 60 })

Auth

Auth is powered by Better-Auth.

In frontend, use the signin(), signout() and useAuth() composable to access auth state and methods:

const session = useSession()
session.value?.user // current user info

Better Auth configuration is located in app/utils/auth.ts(frontend) and server/utils/auth(backend).

Re-run generate Better Auth schema command bun run gen:ba and bun run gen:db after modifying auth configuration.

Frontend

Whenever possible, use Pinia to place reusable logic in app/composables and place reusable components in app/components.

Use NuxtUI to build your application's user interface with pre-built, customizable components that follow best practices for accessibility and design.

Use VueUse to access a collection of essential Vue Composition Utilities that can help you build reactive and efficient applications.

Backend

Whenever possible, place reusable backend logic in server/utils and API route handlers in server/api.

Use Zod for schema validation and type inference in your NuxtHub application.