readysite / website / internal / content / seed / notes.go
7.1 KB
notes.go
package seed

import (
	"log"

	"github.com/readysite/readysite/website/models"
)

// Notes seeds default convention notes for the AI assistant.
func Notes() {
	if models.Notes.Count("") > 0 {
		return // Already seeded
	}

	log.Println("seed: creating default notes...")

	notes := []*models.Note{
		{
			Type:     models.NoteTypeConvention,
			Category: models.NoteCategoryStyle,
			Title:    "Use DaisyUI v5 Components",
			Content: `When creating pages, use DaisyUI v5 components built on Tailwind CSS v4.

Key DaisyUI v5 patterns:
- Cards: class="card bg-base-100 shadow-xl" with card-body, card-title, card-actions
- Buttons: class="btn btn-primary" (also: btn-secondary, btn-ghost, btn-outline, btn-sm, btn-lg)
- Forms: Use floating-label pattern: <label class="floating-label"><span>Label</span><input class="input input-bordered" /></label>
- Modals: <dialog class="modal"> with modal-box, use showModal() to open
- Navigation: class="navbar bg-base-100" with navbar-start, navbar-center, navbar-end
- Alerts: class="alert alert-info" (also: alert-success, alert-warning, alert-error)
- Badges: class="badge badge-primary"
- Tables: class="table" with table-zebra for striped rows

Theme colors: primary, secondary, accent, neutral, base-100/200/300, info, success, warning, error
Use /70, /50, /30 opacity suffixes for muted text: text-base-content/70`,
			Source: models.NoteSourceAI,
			Active: true,
		},
		{
			Type:     models.NoteTypeConvention,
			Category: models.NoteCategoryStyle,
			Title:    "Tailwind CSS v4 Patterns",
			Content: `Use Tailwind CSS v4 utility classes for styling.

Layout:
- Flexbox: flex, flex-col, flex-row, items-center, justify-between, gap-4
- Grid: grid, grid-cols-1, md:grid-cols-2, lg:grid-cols-3, gap-6
- Container: container, mx-auto, px-4, max-w-2xl

Spacing: p-4, px-6, py-8, m-2, mb-4, space-y-4
Typography: text-sm, text-lg, text-xl, font-bold, font-semibold
Colors: text-base-content, bg-base-200, border-base-300

Responsive prefixes: sm:, md:, lg:, xl:
State variants: hover:, focus:, active:

Common patterns:
- Full height page: min-h-screen flex flex-col
- Centered content: flex items-center justify-center
- Card hover effect: hover:shadow-xl transition-all duration-300`,
			Source: models.NoteSourceAI,
			Active: true,
		},
		{
			Type:     models.NoteTypeConvention,
			Category: models.NoteCategoryBehavior,
			Title:    "HTMX for Dynamic Interactions",
			Content: `Use HTMX for dynamic interactions instead of client-side JavaScript frameworks.

Core attributes:
- hx-get="/url" - GET request to URL
- hx-post="/url" - POST request (also: hx-put, hx-patch, hx-delete)
- hx-target="#id" - Where to put the response (CSS selector)
- hx-swap="innerHTML" - How to swap (innerHTML, outerHTML, beforeend, afterbegin, none)
- hx-trigger="click" - What triggers the request (click, change, submit, load, every 5s)

Forms:
- hx-post="/api/endpoint" hx-target="#result" - Submit form via AJAX
- hx-disabled-elt="find button" - Disable button during request
- hx-indicator="#spinner" - Show loading indicator

Collection API endpoints:
- GET /api/collections/{id}/documents - List documents
- POST /api/collections/{id}/documents - Create document
- PUT /api/collections/{id}/documents/{docId} - Update document
- DELETE /api/collections/{id}/documents/{docId} - Delete document

Example form:
<form hx-post="/api/collections/posts/documents" hx-target="#posts-list" hx-swap="beforeend">
    <input name="title" class="input input-bordered" required />
    <button class="btn btn-primary">Add</button>
</form>`,
			Source: models.NoteSourceAI,
			Active: true,
		},
		{
			Type:     models.NoteTypeConvention,
			Category: models.NoteCategoryStructure,
			Title:    "HATEOAS Architecture",
			Content: `ReadySite follows HATEOAS (Hypermedia as the Engine of Application State) principles.

Key concepts:
- Server returns HTML, not JSON - the server decides what the UI looks like
- Links and forms in the response tell the client what actions are available
- State is managed server-side, not in client JavaScript
- HTMX sends requests and swaps HTML responses into the page

Benefits:
- No client-side state management (no Redux, no Zustand)
- Progressive enhancement - works without JavaScript
- Simpler debugging - view source shows actual state
- SEO-friendly - content is in the HTML

Pattern for pages:
1. Page loads with initial HTML from server
2. User interactions trigger HTMX requests
3. Server returns HTML fragments
4. HTMX swaps fragments into the page

Always return HTML from endpoints, not JSON. Use template partials for reusable HTML fragments.`,
			Source: models.NoteSourceAI,
			Active: true,
		},
		{
			Type:     models.NoteTypeConvention,
			Category: models.NoteCategoryStructure,
			Title:    "Using Collections for Dynamic Data",
			Content: `Collections are dynamic data tables (like PocketBase). Use them for blogs, products, team members, etc.

Creating collections:
- Use create_collection tool with name and schema fields
- Field types: text, number, bool, date, select, email, url, json

Displaying collection data in pages:
{{with $items := documents "collection_id"}}
  {{range $item := $items}}
    <div>{{$item.GetString "title"}}</div>
  {{end}}
{{else}}
  <p>No items yet</p>
{{end}}

Document methods:
- $doc.GetString "field" - Get string field
- $doc.GetInt "field" - Get integer field
- $doc.GetBool "field" - Get boolean field
- $doc.GetTime "field" - Get time field (use .Format "Jan 2, 2006")
- $doc.ID - Get document ID

Filtering and ordering:
{{documents "posts" "WHERE published = true ORDER BY CreatedAt DESC"}}

Single document by ID:
{{with $post := document "doc-id"}}...{{end}}
Or with query param:
{{with $post := document (.query.Get "id")}}...{{end}}`,
			Source: models.NoteSourceAI,
			Active: true,
		},
		{
			Type:     models.NoteTypeConvention,
			Category: models.NoteCategoryStructure,
			Title:    "Page Structure with Partials",
			Content: `Every page should be a complete HTML document using partials for consistency.

Required structure:
<!DOCTYPE html>
<html lang="en" data-theme="light">
<head>
    {{partial "head"}}
    <title>Page Title - {{site_name}}</title>
</head>
<body class="min-h-screen bg-base-200 flex flex-col">
    {{partial "header"}}
    <main class="container mx-auto p-8 flex-1">
        <!-- Page content here -->
    </main>
    {{partial "footer"}}
</body>
</html>

Built-in partials:
- {{partial "head"}} - Meta tags, Tailwind/DaisyUI/HTMX CDN links
- {{partial "header"}} - Navigation bar with site name and menu
- {{partial "footer"}} - Footer with copyright

Template functions:
- {{site_name}} - Returns the site name from settings
- {{partial "name"}} - Include a partial by ID
- {{documents "collection"}} - Get collection documents
- {{document "id"}} - Get single document
- {{page "id"}} - Get a page
- {{pages}} - Get root pages
- {{published_pages}} - Get published root pages`,
			Source: models.NoteSourceAI,
			Active: true,
		},
	}

	for _, note := range notes {
		if _, err := models.Notes.Insert(note); err != nil {
			log.Printf("seed: failed to insert note %q: %v", note.Title, err)
		}
	}

	log.Println("seed: default notes created successfully")
}
← Back