Skip to content

Commit 199352f

Browse files
oyvindbergclaude
andauthored
Enhance Typo website with comprehensive improvements and documentation (#151)
* Enhance Typo website with comprehensive improvements and documentation This major update transforms the Typo website from a basic documentation site into a comprehensive, professional marketing and documentation platform that accurately showcases Typo's capabilities with real, compilable code examples. ## 🎨 Website Visual & UX Improvements - **Professional Design**: Modern, clean layout with improved typography and spacing - **Enhanced Feature Showcase**: Comprehensive component displaying all major Typo features - **Improved Navigation**: Reorganized sidebar with logical grouping and "Advanced Features" section - **Consistent Branding**: Updated logo and generated matching favicon (SVG + ICO) - **Better Code Examples**: Split SQL/Scala code blocks with proper syntax highlighting ## 📚 Documentation Enhancements - **DSL In-Depth Guide**: Complete 400+ line comprehensive DSL documentation covering: - Basic selects, where clauses, joins, updates, deletes - Foreign key navigation with joinFk - Tuple syntax with ~ operator - Null handling and type safety - Performance considerations and SQL printing - **Database Libraries Section**: Added detailed customization docs for Anorm/Doobie/ZIO-JDBC - **Fixed Broken Links**: Resolved anchor reference issues and updated relative paths ## 🔧 Development Infrastructure - **Frontpage Code Generation**: Real PostgreSQL schema generates accurate code examples - Created `init/data/frontpage/` with comprehensive test schema - Built `GeneratedFrontpage.scala` script for automatic code generation - Added domains, enums, foreign keys, composite keys, and complex relationships - **Asset Generation Scripts**: - `generate-logo.js` - SVG logo with purple gradient - `generate-favicon.js` - Matching favicon in SVG/ICO formats with npm integration - **Documentation Workflow**: Added CLAUDE.md section documenting the manual frontpage update process ## 📋 Content & Accuracy Improvements - **Real Code Examples**: All website examples now generated from actual Typo output - **Consistent Naming**: Converted all examples from plural to singular table names - **Marketing Refinements**: - Removed exaggerated claims ("10x faster" → "faster") - Added specific Hibernate criticisms in ORM comparisons - Enhanced type safety messaging with nullability handling - Updated feature descriptions for accuracy - **Comprehensive Coverage**: Added examples for: - Composite primary keys (separated SQL/Scala blocks) - PostgreSQL domains and enums - Streaming operations and batch processing - Testing with mocks and TestInsert - Advanced PostgreSQL types (arrays, JSONB, geometric types) ## 🛠️ Technical Improvements - **Build System**: Added bleep script for frontpage code generation - **Git Management**: Added `frontpage-generated/` to gitignore (generated code not tracked) - **Modern Favicon Support**: SVG favicon for modern browsers, ICO fallback for legacy - **Broken Anchor Fixes**: Resolved documentation link issues - **mdoc Integration**: All DSL examples compile correctly with proper invisible setup blocks ## 📊 Impact - **39 files changed**: 3,379 insertions, 500 deletions - **New Files**: 9 new components and scripts - **Documentation**: 400+ lines of new DSL documentation - **Schema**: 153-line comprehensive PostgreSQL test schema - **Real Examples**: All code samples now generated from working Typo output This update establishes Typo's website as a professional, accurate showcase of its capabilities while providing developers with comprehensive, tested documentation and real code examples they can trust and use immediately. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * Add GitHub Actions workflow for automatic website deployment - Deploy documentation site to GitHub Pages on main branch pushes - Builds docs with bleep generate-docs + Docusaurus - Uses standard GitHub Pages deployment action - Site will be available at https://oyvindberg.github.io/typo/ 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * Format code with bleep fmt 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent ad7f826 commit 199352f

42 files changed

Lines changed: 4611 additions & 126 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy-docs.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Deploy Documentation
2+
on:
3+
push:
4+
branches: [ 'main' ]
5+
workflow_dispatch:
6+
7+
permissions:
8+
contents: read
9+
pages: write
10+
id-token: write
11+
12+
concurrency:
13+
group: "pages"
14+
cancel-in-progress: false
15+
16+
jobs:
17+
build:
18+
timeout-minutes: 20
19+
runs-on: ubuntu-latest
20+
if: "!contains(github.event.head_commit.message, 'ci skip')"
21+
env:
22+
PG_MAJOR: 14
23+
steps:
24+
- uses: actions/checkout@v4
25+
- uses: bleep-build/bleep-setup-action@0.0.1
26+
- uses: coursier/cache-action@v6
27+
with:
28+
extraFiles: bleep.yaml
29+
30+
- name: Start up Postgres
31+
run: docker compose up -d
32+
33+
- name: Generate docs with mdoc
34+
run: |
35+
bleep generate-docs
36+
37+
- name: Setup Node.js
38+
uses: actions/setup-node@v4
39+
with:
40+
node-version: '20'
41+
cache: 'npm'
42+
cache-dependency-path: site/package-lock.json
43+
44+
- name: Install dependencies
45+
run: npm ci
46+
working-directory: ./site
47+
48+
- name: Build website
49+
run: npm run build
50+
working-directory: ./site
51+
52+
- name: Setup Pages
53+
uses: actions/configure-pages@v3
54+
55+
- name: Upload artifact
56+
uses: actions/upload-pages-artifact@v2
57+
with:
58+
path: ./site/build
59+
60+
deploy:
61+
environment:
62+
name: github-pages
63+
url: ${{ steps.deployment.outputs.page_url }}
64+
runs-on: ubuntu-latest
65+
needs: build
66+
steps:
67+
- name: Deploy to GitHub Pages
68+
id: deployment
69+
uses: actions/deploy-pages@v2

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ target
88
.vscode
99
site/docs
1010
myproject/
11+
frontpage-generated/

CLAUDE.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,45 @@ npm run serve
251251
- Check `bleep.yaml` for script configurations
252252
- Use database introspection tools to verify schema
253253

254+
### Working with Frontpage Code Examples
255+
256+
The website's code examples are generated from real Typo code using the `frontpage` schema in the test database. This ensures that all examples shown on the website are accurate and compile correctly.
257+
258+
**Schema Location**: `init/data/frontpage/` contains:
259+
- `schema.sql` - Database schema for frontpage examples
260+
- `*.sql` - SQL files that generate Typo repositories and types
261+
262+
**Generation Process**:
263+
1. **Modify Schema**: Edit files in `init/data/frontpage/` to change database structure or add new examples
264+
2. **Restart Database**: Run `docker-compose down && docker-compose up -d` to apply schema changes
265+
3. **Generate Code**: Run `bleep run GeneratedFrontpage` to generate fresh Scala code
266+
4. **Update Website**: Manually copy the generated code from `frontpage-generated/` into website components in `site/src/components/FeatureShowcase/index.js`
267+
268+
**Important Notes**:
269+
- The `frontpage-generated/` directory is gitignored - we don't check in generated code
270+
- The frontpage schema uses real PostgreSQL features (domains, enums, foreign keys) to showcase Typo's capabilities
271+
- Always verify examples compile by running `bleep generate-docs` after updating website code
272+
- This is the only part of the documentation workflow that requires manual copying of generated code
273+
- Website logo and favicon can be regenerated using `site/scripts/generate-logo.js` and `npm run generate-favicon`
274+
275+
**Example Workflow**:
276+
```bash
277+
# 1. Edit schema
278+
vi init/data/frontpage/schema.sql
279+
280+
# 2. Restart database
281+
docker-compose down && docker-compose up -d
282+
283+
# 3. Generate fresh code
284+
bleep run GeneratedFrontpage
285+
286+
# 4. Copy relevant parts to website (manual step)
287+
# Look in frontpage-generated/ for the code you need
288+
289+
# 5. Verify documentation builds
290+
bleep generate-docs
291+
```
292+
254293
## Troubleshooting
255294

256295
### Common Issues

bleep.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ scripts:
109109
generate-docs:
110110
main: scripts.GenDocumentation
111111
project: typo-scripts-doc
112+
generate-frontpage:
113+
main: scripts.GeneratedFrontpage
114+
project: typo-scripts
112115
generate-sources:
113116
main: scripts.GeneratedSources
114117
project: typo-scripts
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
-- Advanced parameter syntax example
2+
SELECT p.*, a.city, e.salary
3+
FROM frontpage.person p
4+
JOIN frontpage.address a ON p.address_id = a.id
5+
LEFT JOIN frontpage.employee e ON p.id = e.person_id
6+
WHERE p.id = :person_id!
7+
AND p.created_at >= :since!
8+
AND a.country = :country:String?
9+
AND (:max_salary? IS NULL OR e.salary <= :max_salary)

init/data/frontpage/schema.sql

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
-- Schema for Typo front page examples
2+
CREATE SCHEMA IF NOT EXISTS frontpage;
3+
4+
-- PostgreSQL domains example (create first)
5+
CREATE DOMAIN frontpage.email AS TEXT CHECK (VALUE ~ '^[^@]+@[^@]+\.[^@]+$');
6+
7+
-- Enum type example
8+
CREATE TYPE frontpage.user_status AS ENUM ('active', 'inactive', 'suspended');
9+
CREATE TYPE frontpage.order_status AS ENUM ('pending', 'active', 'shipped', 'cancelled');
10+
CREATE TYPE frontpage.user_role AS ENUM ('admin', 'manager', 'employee');
11+
12+
-- Basic example tables
13+
CREATE TABLE frontpage.department (
14+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
15+
name TEXT NOT NULL,
16+
budget DECIMAL(12,2)
17+
);
18+
19+
CREATE TABLE frontpage.user (
20+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
21+
email frontpage.email NOT NULL UNIQUE,
22+
name TEXT NOT NULL,
23+
created_at TIMESTAMP DEFAULT NOW(),
24+
department_id UUID REFERENCES frontpage.department(id),
25+
status frontpage.user_status DEFAULT 'active',
26+
verified BOOLEAN DEFAULT false
27+
);
28+
29+
-- Relationships example tables
30+
CREATE TABLE frontpage.product (
31+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
32+
name TEXT NOT NULL,
33+
price DECIMAL(10,2) NOT NULL,
34+
in_stock BOOLEAN DEFAULT true,
35+
quantity INTEGER DEFAULT 0,
36+
last_restocked TIMESTAMP,
37+
last_modified TIMESTAMP DEFAULT NOW(),
38+
tags TEXT[] DEFAULT '{}',
39+
categories INTEGER[] DEFAULT '{}',
40+
prices DECIMAL[] DEFAULT '{}',
41+
attributes JSONB[] DEFAULT '{}'
42+
);
43+
44+
CREATE TABLE frontpage.category (
45+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
46+
name TEXT NOT NULL
47+
);
48+
49+
CREATE TABLE frontpage.product_category (
50+
product_id UUID REFERENCES frontpage.product(id),
51+
category_id UUID REFERENCES frontpage.category(id),
52+
PRIMARY KEY (product_id, category_id)
53+
);
54+
55+
CREATE TABLE frontpage.order (
56+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
57+
user_id UUID REFERENCES frontpage.user(id),
58+
product_id UUID REFERENCES frontpage.product(id),
59+
status frontpage.order_status DEFAULT 'pending',
60+
total DECIMAL(10,2) NOT NULL,
61+
created_at TIMESTAMP DEFAULT NOW(),
62+
shipped_at TIMESTAMP
63+
);
64+
65+
CREATE TABLE frontpage.order_item (
66+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
67+
order_id UUID REFERENCES frontpage.order(id),
68+
product_id UUID REFERENCES frontpage.product(id),
69+
quantity INTEGER NOT NULL,
70+
price DECIMAL(10,2) NOT NULL,
71+
shipped_at TIMESTAMP
72+
);
73+
74+
-- Customers table for joins
75+
CREATE TABLE frontpage.customer (
76+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
77+
user_id UUID REFERENCES frontpage.user(id),
78+
company_name TEXT,
79+
credit_limit DECIMAL(10,2),
80+
verified BOOLEAN DEFAULT false
81+
);
82+
83+
-- Many-to-many example
84+
CREATE TABLE frontpage.role (
85+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
86+
name TEXT NOT NULL UNIQUE
87+
);
88+
89+
CREATE TABLE frontpage.user_role (
90+
user_id UUID REFERENCES frontpage.user(id),
91+
role_id UUID REFERENCES frontpage.role(id),
92+
assigned_at TIMESTAMP DEFAULT NOW(),
93+
PRIMARY KEY (user_id, role_id)
94+
);
95+
96+
-- Composite key example
97+
CREATE TABLE frontpage.permission (
98+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
99+
name TEXT NOT NULL UNIQUE
100+
);
101+
102+
CREATE TABLE frontpage.user_permission (
103+
user_id UUID REFERENCES frontpage.user(id),
104+
permission_id UUID REFERENCES frontpage.permission(id),
105+
granted_at TIMESTAMP DEFAULT NOW(),
106+
PRIMARY KEY (user_id, permission_id)
107+
);
108+
109+
-- Advanced PostgreSQL types example
110+
CREATE TABLE frontpage.location (
111+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
112+
name TEXT NOT NULL,
113+
position POINT,
114+
area POLYGON,
115+
ip_range INET,
116+
metadata JSONB DEFAULT '{}'
117+
);
118+
119+
-- Testing examples
120+
CREATE TABLE frontpage.company (
121+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
122+
name TEXT NOT NULL
123+
);
124+
125+
ALTER TABLE frontpage.department ADD COLUMN company_id UUID REFERENCES frontpage.company(id);
126+
ALTER TABLE frontpage.user ADD COLUMN manager_id UUID REFERENCES frontpage.user(id);
127+
ALTER TABLE frontpage.user ADD COLUMN role frontpage.user_role DEFAULT 'employee';
128+
129+
-- Complex join examples
130+
CREATE TABLE frontpage.employee (
131+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
132+
person_id UUID UNIQUE NOT NULL,
133+
salary DECIMAL(10,2)
134+
);
135+
136+
CREATE TABLE frontpage.person (
137+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
138+
name TEXT NOT NULL,
139+
address_id UUID,
140+
created_at TIMESTAMP DEFAULT NOW()
141+
);
142+
143+
CREATE TABLE frontpage.address (
144+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
145+
city TEXT NOT NULL,
146+
country TEXT NOT NULL
147+
);
148+
149+
ALTER TABLE frontpage.person ADD CONSTRAINT fk_address
150+
FOREIGN KEY (address_id) REFERENCES frontpage.address(id);
151+
152+
ALTER TABLE frontpage.employee ADD CONSTRAINT fk_person
153+
FOREIGN KEY (person_id) REFERENCES frontpage.person(id);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
-- sql/update-user-status.sql
2+
UPDATE frontpage.user
3+
SET
4+
status = :new_status:frontpage.user_status!,
5+
created_at = NOW() -- using created_at as modified_at since we don't have modified_at column
6+
WHERE id = :user_id!
7+
AND status != :new_status
8+
RETURNING
9+
id,
10+
name,
11+
status,
12+
created_at as "modified_at:java.time.LocalDateTime!"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- sql/user-analytics.sql
2+
SELECT
3+
u.name,
4+
u.email,
5+
COUNT(o.id) as order_count,
6+
SUM(o.total) as lifetime_value,
7+
MAX(o.created_at) as last_order_date
8+
FROM frontpage.user u
9+
LEFT JOIN frontpage.order o ON u.id = o.user_id
10+
WHERE u.created_at >= :start_date:LocalDate!
11+
AND u.status = :status:frontpage.user_status?
12+
GROUP BY u.id, u.name, u.email
13+
HAVING SUM(o.total) > :min_value:BigDecimal!
14+
ORDER BY lifetime_value DESC
15+
LIMIT :limit:Int!

init/install.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ psql -d Adventureworks < /docker-entrypoint-initdb.d/data/install.sql
1212
# this should have had a database by itself, but let's be lazy for now
1313
psql -d Adventureworks < /docker-entrypoint-initdb.d/data/test-tables.sql
1414
psql -d Adventureworks < /docker-entrypoint-initdb.d/data/issue148.sql
15+
16+
# Front page examples
17+
psql -d Adventureworks < /docker-entrypoint-initdb.d/data/frontpage/schema.sql

site-in/customization/overview.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,24 @@ val options = Options(
3939
| `rewriteDatabase` | Let's you perform arbitrary rewrites of database schema snapshot. you can add/remove rows, foreign keys and so on. |
4040
| `openEnums` | Controls if you want to tag tables ids as [open string enums](../type-safety/open-string-enums.md) |
4141

42+
## Database Libraries
43+
44+
Typo supports multiple Scala database libraries, each with specific optimizations:
45+
46+
- **Anorm** (`DbLibName.Anorm`) - Lightweight SQL parser for Play Framework
47+
- **Doobie** (`DbLibName.Doobie`) - Functional JDBC layer for Cats Effect
48+
- **ZIO-JDBC** (`DbLibName.ZioJdbc`) - Type-safe JDBC wrapper for ZIO
49+
50+
Each library generates code optimized for that specific ecosystem, including appropriate return types, error handling, and integration patterns.
51+
52+
```scala
53+
val options = Options(
54+
pkg = "myapp.db",
55+
dbLib = Some(DbLibName.Anorm), // Choose your library
56+
// ... other options
57+
)
58+
```
59+
4260
## Development options
4361

4462
| Field Name | Effect |

0 commit comments

Comments
 (0)