Installs: 0
Used in: 1 repos
Updated: 2d ago
$
npx ai-builder add skill leobar37/linkInstalls to .claude/skills/link/
# Wellness Link - Full-Stack Monorepo Expert
Expert for the wellness-link monorepo. Combines frontend (React 19 + Tailwind v4 + shadcn/ui) and backend (Bun + Elysia + Drizzle) development with monorepo-specific workflows.
## Available Documentation
### Patterns
- **[Full-Stack Workflow](patterns/fullstack-workflow.md)** - Complete guide for implementing features across packages
- **[Monorepo Commands](patterns/monorepo-commands.md)** - Bun workspace commands, development, and troubleshooting
### Agent References
- **[Web Agent](reference/web-agent.md)** - Quick reference to `.claude/agent/web.md`
- **[API Agent](reference/api-agent.md)** - Quick reference to `.claude/agent/api.md`
## Monorepo Structure
```
wellness-link/
├── packages/
│ ├── web/ # React 19 + Vite (port 5176)
│ └── api/ # Bun + Elysia (port 5300)
├── bunfig.toml # Bun workspaces
└── package.json # Root workspace
```
## Critical Cross-Package Rules
### 1. Type Sharing
```typescript
// API defines types, web imports via edenTreaty
// packages/api/src/index.ts
export const app = new Elysia()...
// packages/web/src/lib/api.ts
import type { App } from "@wellness-link/api"
export const api = edenTreaty<App>("http://localhost:5300")
```
### 2. Language & Theme
- **User-facing text**: Spanish (buttons, forms, messages)
- **Technical docs**: English (code, comments, README)
- **Theme**: Always use CSS variables (`bg-background`, `text-foreground`)
### 3. Workspace Commands
```bash
# Run from root
bun --filter @wellness-link/web dev # Frontend only
bun --filter @wellness-link/api dev # Backend only
# Development (both in parallel)
bun run dev # Runs both packages
```
## Web Package (packages/web)
### Stack
- React 19 + React Router 7 (file-based)
- Tailwind CSS v4 + shadcn/ui
- TanStack Query (server state)
- React Hook Form + Zod (forms)
### Critical Rules
```typescript
// ALWAYS use @/ alias
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
// ALWAYS use cn() for classes
<div className={cn("flex", className, isActive && "bg-primary")} />
// ALWAYS Spanish UI text
<Button>Guardar Cambios</Button>
toast.success("Perfil actualizado")
```
### Data Fetching
```typescript
const { data, isLoading } = useQuery({
queryKey: ["profiles"],
queryFn: async () => {
const { data, error } = await api.api.profiles.get()
if (error) throw error
return data
},
})
```
## API Package (packages/api)
### Stack
- Bun (runtime)
- Elysia (framework)
- Drizzle ORM (PostgreSQL)
- Better Auth (authentication)
### Critical Rules
```typescript
// Table names are SINGULAR
import { profile, asset, socialLink } from "../../db/schema"
// ALWAYS register services in plugins/services.ts
export const servicesPlugin = new Elysia({ name: "services" }).derive(
{ as: "global" },
async () => {
const featureRepo = new FeatureRepository();
const featureService = new FeatureService(featureRepo);
return { services: { featureRepo, featureService } };
},
);
// Access relations via name
const platform = click.socialLink.platform; // ✅
const platform = click.platform; // ❌
```
### Route Pattern
```typescript
export const featureRoutes = new Elysia({ prefix: "/feature" })
.use(errorMiddleware)
.use(servicesPlugin)
.use(authGuard)
.get("/", ({ ctx, services }) => services.featureService.getAll(ctx!))
.post("/", ({ body, ctx, services, set }) => {
set.status = 201;
return services.featureService.create(ctx!, body);
}, { body: t.Object({ name: t.String() }) });
```
## Full-Stack Feature Workflow
### 1. Define API Contract
```typescript
// packages/api/src/api/routes/feature.ts
export const featureRoutes = new Elysia({ prefix: "/feature" })
.get("/", () => [...])
.post("/", ({ body }) => body, {
body: t.Object({
name: t.String(),
description: t.String(),
})
});
```
### 2. Add Route to App
```typescript
// packages/api/src/index.ts
import { featureRoutes } from "./api/routes/feature"
export const app = new Elysia()
.use(featureRoutes)
...
```
### 3. Frontend Integration
```typescript
// packages/web/src/hooks/use-features.ts
export function useFeatures() {
return useQuery({
queryKey: ["features"],
queryFn: async () => {
const { data, error } = await api.api.feature.get()
if (error) throw error
return data
},
})
}
// packages/web/src/components/FeatureForm.tsx
const mutation = useMutation({
mutationFn: async (values: { name: string; description: string }) => {
const { data, error } = await api.api.feature.post(values)
if (error) throw error
return data
},
})
```
## Common Patterns
### Authentication Flow
```typescript
// API: Better Auth automatic
// packages/api/src/lib/auth.ts
export const auth = betterAuth({ ... })
// Web: Use auth client
// packages/web/src/hooks/use-auth.ts
const { data: session } = useSession()
```
### File Upload (Full-Stack)
```typescript
// API: Asset service
const asset = await services.assetService.create(ctx, {
file: request.file,
type: "avatar",
})
// Web: Form with file input
const { mutate } = useMutation({
mutationFn: async (file: File) => {
const formData = new FormData()
formData.append("file", file)
const { data } = await api.api.assets.post(formData)
return data
},
})
```
### Error Handling
```typescript
// API: HTTP exceptions
throw new NotFoundException("Profile not found") // 404
throw new ConflictException("Username exists") // 409
// Web: React Query + toast
onError: (error) => {
toast.error(error.message || "Error al guardar")
}
```
## Monorepo Best Practices
### 1. Development Setup
```bash
# Install all dependencies
bun install
# Start both packages
bun run dev
# Type check entire monorepo
bun run typecheck
```
### 2. Database Migrations
```bash
# Generate migration
cd packages/api && bun run db:generate
# Apply migration
bun run db:migrate
# Seed data
bun run db:seed
```
### 3. Cross-Package Changes
**Order**: API first, then Web
1. Add DB schema/migration
2. Create repository + service
3. Add API route
4. Create frontend hook
5. Build UI component
### 4. Type Safety
```typescript
// API exports App type
export type App = typeof app
// Web imports and uses it
import type { App } from "@wellness-link/api"
export const api = edenTreaty<App>("http://localhost:5300")
```
## Key Tables
- **user**: Better Auth authentication
- **profile**: Wellness professional info
- **socialLink**: Orderable social media links
- **healthSurvey**: Visitor survey responses
- **analytics**: Views and clicks tracking
- **asset**: File uploads (avatars, images)
## Quick Commands
```bash
# Web development
cd packages/web
bun run dev # Port 5176
bun run build
bun run lint
# API development
cd packages/api
bun run dev # Port 5300
bun run db:seed
bun run db:reset
bun run lint
# Monorepo (from root)
bun run dev # Both packages
bun install # All dependencies
```
## When to Use This Skill
- Implementing features that span both web and api
- Setting up new API endpoints with frontend integration
- Working with shared types across packages
- Monorepo workflow questions
- Cross-package refactoring
- Full-stack feature developmentQuick Install
$
npx ai-builder add skill leobar37/linkDetails
- Type
- skill
- Author
- leobar37
- Slug
- leobar37/link
- Created
- 6d ago