Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
node_modules

# Output
.output
.vercel
.netlify
.wrangler
/.svelte-kit
/build

# OS
.DS_Store
Thumbs.db

# Env
.env
.env.*
!.env.example
!.env.test

# Vite
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
64 changes: 64 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Essential Development Commands

```bash
# Development
npm run dev # Start development server
npm run build # Build for production
npm run start # Start production server
npm run preview # Preview production build

# Code Quality
npm run check # TypeScript type checking
npm run check:watch # TypeScript type checking in watch mode
npm run lint # Run ESLint and Prettier checks
npm run format # Format code with Prettier

# Database Setup
npm run db:setup # Initialize database schema (requires DATABASE_URL env var)
psql -d database_name -f schema.sql # Alternative: direct psql command
```

## Architecture Overview

This is a SvelteKit + PostgreSQL guestbook application with the following key architectural patterns:

### Database Layer (`src/lib/database.ts`)
- Uses `pg` PostgreSQL client with connection pooling
- `MessageService` class provides data access methods
- Type-safe interfaces: `GuestbookMessage` and `MessageInsert`
- SSL configuration for production environments

### Server-Side Logic (`src/routes/+page.server.ts`)
- Load function fetches messages with error handling
- Form actions handle message creation with validation
- Input sanitization and length limits (name: 100 chars, message: 500 chars)

### Component Structure
- Reusable UI components in `src/lib/components/`
- `MessageCard.svelte` - displays individual guestbook entries
- `MessageForm.svelte` - form for creating new entries
- `Header.svelte`, `Navigation.svelte` - layout components

### Database Schema
- Single table: `guestbook_messages`
- Required fields: `name`, `message`
- Optional fields: `email`, `location`, `website`
- Indexed on `created_at` for performance

## Environment Configuration

Required environment variable:
- `DATABASE_URL` - PostgreSQL connection string

The application automatically configures SSL for production environments and includes proper connection pooling.

## Package Management
The project has merge conflict markers in package.json. Resolve these before development:
- Uses npm as the package manager (despite README mentioning bun)
- Node.js adapter configured for deployment
- Tailwind CSS v4 for styling
- TypeScript with strict mode enabled
52 changes: 52 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# syntax = docker/dockerfile:1

# Adjust BUN_VERSION as desired
ARG BUN_VERSION=1.2.19
FROM oven/bun:${BUN_VERSION}-slim AS base

# Base arguments
ARG DATABASE_URL="dummy"

LABEL fly_launch_runtime="SvelteKit"

# SvelteKit app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"


# Throw-away build stage to reduce size of final image
FROM base AS build

# Install packages needed to build node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential pkg-config python-is-python3

# Install node modules
COPY .npmrc bun.lockb package.json ./
RUN bun install

# Copy application code
COPY . .

# Build application
RUN bun --bun run build

# Remove development dependencies
RUN rm -rf node_modules && \
bun install --ci


# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app/build /app/build
COPY --from=build /app/node_modules /app/node_modules
COPY --from=build /app/package.json /app

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
ENV DATABASE_URL="dummy"
CMD [ "bun", "run", "start" ]
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tools]
node = "24.6.0"
95 changes: 53 additions & 42 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
{
"name": "sveltekit-sample",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "node build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"format": "prettier --write .",
"lint": "prettier --check . && eslint ."
},
"devDependencies": {
"@types/pg": "^8.11.10",
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
"@sveltejs/adapter-node": "^5.2.12",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.0.0",
"typescript-eslint": "^8.20.0",
"vite": "^7.0.4"
},
"dependencies": {
"pg": "^8.12.0"
}
}
"name": "sveltekit-sample",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"start": "node build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"format": "prettier --write .",
"lint": "prettier --check . && eslint .",
"db:setup": "psql $DATABASE_URL -f schema.sql"
},
"devDependencies": {
"@types/pg": "^8.11.10",
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.18.0",
"@sveltejs/adapter-node": "^5.3.1",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15",
"@tailwindcss/vite": "^4.0.0",
"eslint": "^9.18.0",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-svelte": "^3.0.0",
"globals": "^16.0.0",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
"typescript": "^5.0.0",
"typescript-eslint": "^8.20.0",
"vite": "^7.0.4"
},
"dependencies": {
"pg": "^8.12.0"
},
"dockerfile": {
"envs": {
"deploy": {
"DATABASE_URL": "dummy"
}
},
"args": {
"base": {}
}
}
}