Markdown Converter
Agent skill for markdown-converter
This document provides essential information for AI agents and developers working on this codebase.
Sign in to like and favorite skills
This document provides essential information for AI agents and developers working on this codebase.
Prompts is a weekly creative prompt community app where admins publish three-word prompts and users submit photos/text inspired by those words.
# Install dependencies bun install # Set up environment variables cp .env.example .env # Edit .env with your credentials # Run database migrations bunx prisma migrate dev --schema apps/web/prisma/schema.prisma # Start development server bun run dev
The app will be available at http://localhost:3000
| Document | Description |
|---|---|
| apps/web/docs/DATABASE.md | Database schema, Prisma usage, migrations, image storage |
| apps/web/docs/IMAGE-HANDLING.md | Upload flow, presign, post-processing workflow, resize/WebP, metadata |
| apps/web/docs/FRONTEND.md | React components, theming, UI patterns |
| apps/web/docs/INTERNATIONALIZATION.md | Translation system, i18n patterns, adding new languages |
| apps/web/docs/CREATOR-PROTECTIONS.md | Watermarking, download prevention, AI training opt-out |
| apps/web/docs/HINTS.md | Contextual help and hint system, tutorial management |
| apps/web/docs/PROGRESSIONS.md | Progressions (work-in-progress steps for submissions): data model, API, form, view, lightbox |
apps/web/app/ # Next.js App Router pages and API routes ├── api/ # API endpoints ├── admin/ # Admin dashboard (prompts, users) ├── play/ # User submission interface ├── this-week/ # Gallery view └── history/ # User's past submissions apps/web/components/ # Shared React components ├── ui/ # shadcn/ui components (button, dialog, etc.) apps/web/i18n/ # Internationalization configuration ├── config.ts # Supported locales and utilities └── request.ts # next-intl server configuration apps/web/lib/ # Utilities (auth, prisma, helpers) apps/web/messages/ # Translation files ├── en.json # English translations └── es.json # Spanish translations apps/web/prisma/ # Database schema and migrations apps/web/public/ # Static assets apps/web/docs/ # Developer documentation
| Command | Description |
|---|---|
| Start development server |
| Build for production |
| Start production server |
| Run oxlint |
| Format code with Biome |
| Check formatting without changes |
| Run full validation (lint, format, knip, build) |
Important: After making major changes to the codebase (e.g., schema changes, new features, significant refactoring), always run
to ensure everything passes linting, formatting, dependency checks, and builds successfully before completing the task.bun run validate
This project uses Bun as the package manager and runtime. Always use
bun commands:
bun install # Install dependencies bun add <package> # Add dependency bun add -d <package> # Add dev dependency bun run <script> # Run npm script
Fast linter from the OXC project. Run with:
bun run lint
Code formatting via Biome (OXC ecosystem). Configuration in
biome.json:
bun run format # Format all files bun run format:check # Check without modifying
Strict mode enabled. Key settings in
apps/web/tsconfig.json:
strict: true - All strict checks enabled@/* path alias maps to apps/webbunx prisma generate --schema apps/web/prisma/schema.prisma # Regenerate client bunx prisma migrate dev --schema apps/web/prisma/schema.prisma # Create and apply migration bunx prisma studio --schema apps/web/prisma/schema.prisma # Open database GUI
any@/* import alias for project imports// Good import { prisma } from "@/lib/prisma"; import type { User } from "@/app/generated/prisma/client"; // Avoid import { prisma } from "../../../lib/prisma";
"use client" at top)apps/web/components when reused across pages// Server Component (default) export default async function Page() { const data = await fetchData(); return <div>{data}</div>; } // Client Component (when needed) "use client"; export function InteractiveComponent() { const [state, setState] = useState(); // ... }
Components are located in
apps/web/components/ui/. Import and use them directly:
import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; <Button variant="default" size="lg">Click me</Button> <Input type="text" placeholder="Enter text" /> <Label htmlFor="input-id">Label text</Label>
The app uses
next-themes for theme management. Users can toggle between light/dark/system via the theme toggle in the header.
apps/web/app/globals.cssdark: prefix for custom dark mode styles when needed// Theme-aware component <div className="bg-background text-foreground"> <Button variant="default">Themed Button</Button> </div>
Important: iOS Safari Dark Mode Issue
iOS Safari has a known issue where dark mode detection fails for cards with gradient backgrounds. When creating cards with custom gradients, you must add explicit CSS rules in
apps/web/app/globals.css with !important flags to ensure proper dark mode styling.
Pattern:
contact-card-blue)!important.dark class rule with dark background hsl(240 10% 3.9%) and !important@media (prefers-color-scheme: dark) rule with same dark background and !importantSee
apps/web/app/globals.css for examples (terms-card, contact-card-blue, contact-card-purple) and apps/web/docs/FRONTEND.md for complete documentation.
bunx shadcn@latest add <component-name>
This will add the component to
apps/web/components/ui/ and update necessary dependencies.
The app uses next-intl for translations with profile-based language preferences.
import { getTranslations } from "next-intl/server"; export default async function Page() { const t = await getTranslations("common"); return <button>{t("save")}</button>; }
"use client"; import { useTranslations } from "next-intl"; export function MyButton() { const t = useTranslations("common"); return <button>{t("save")}</button>; }
// In messages/en.json: "greeting": "Hello, {name}!" t("greeting", { name: "Sarah" }); // "Hello, Sarah!"
See apps/web/docs/INTERNATIONALIZATION.md for complete i18n documentation.
apps/web/app/api/ directoryauth()import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/lib/auth"; export async function POST(request: NextRequest) { const session = await auth(); if (!session?.user) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } // Handle request... }
@/lib/prismaimport { prisma } from "@/lib/prisma"; const user = await prisma.user.findUnique({ where: { id: userId }, });
Required variables (see
.env.example):
| Variable | Description |
|---|---|
| PostgreSQL connection string |
| App URL (http://localhost:3000 for dev) |
| Random secret for NextAuth |
| Google OAuth client ID |
| Google OAuth client secret |
| Cloudflare account ID |
| R2 access key |
| R2 secret key |
| R2 bucket name |
| Public URL for R2 bucket |
const session = await auth(); if (!session?.user) { // Handle unauthenticated } if (!session?.user?.isAdmin) { // Handle non-admin }
/api/upload via FormData/api/submissionsimport { getCurrentPrompt } from "@/lib/prompts"; const prompt = await getCurrentPrompt(); // Returns prompt where now is between weekStart and weekEnd
Important: After making major changes to the codebase (including schema changes, new features, or significant refactoring), always run
to ensure:bun run validate
- Code passes linting checks
- Code is properly formatted
- No unused dependencies or exports exist
- Application builds successfully
Test infrastructure is not yet set up. When adding tests:
- Use Vitest or Jest for unit tests
- Use Playwright for E2E tests
- Place tests adjacent to source files or in
directories__tests__
apps/web/app/ (e.g., apps/web/app/new-page/)page.tsx with default exportapps/web/app/api/ (e.g., apps/web/app/api/endpoint/route.ts)apps/web/prisma/schema.prismabunx prisma migrate dev --schema apps/web/prisma/schema.prisma --name <description>bun run validate after schema changes to ensure builds passapps/web/components/ui/)apps/web/components/ directorybunx shadcn@latest add <component-name>
Components are installed to
components/ui/ and can be imported directly.
bunx prisma generate --schema apps/web/prisma/schema.prisma
DATABASE_URL in .envbunx prisma generate --schema apps/web/prisma/schema.prisma # Restart TypeScript server in your editor
bun run format
If cards with gradient backgrounds show light backgrounds with light text in dark mode on iOS Safari, you need to add explicit CSS rules with
!important flags.
Solution:
apps/web/app/globals.css!important.dark class rule with background: hsl(240 10% 3.9%) !important@media (prefers-color-scheme: dark) rule with same background and !importantExample:
.contact-card-blue { background: linear-gradient(to bottom right, rgb(239 246 255 / 0.5), rgb(255 255 255)) !important; } .dark .contact-card-blue { background: hsl(240 10% 3.9%) !important; } @media (prefers-color-scheme: dark) { .contact-card-blue:not(.light .contact-card-blue) { background: hsl(240 10% 3.9%) !important; } }
Then use the class in your component:
<Card className="contact-card-blue rounded-3xl border-none shadow-sm">
See existing examples in
apps/web/app/globals.css (terms-card, contact-card-blue, contact-card-purple) and apps/web/docs/FRONTEND.md for complete documentation.