snippets/CLAUDE.md
Travis Shears c1f984b8d0
replace XTDB references with Datomic
- Update project overview in README.md and CLAUDE.md to reference Datomic
- Replace documentation links from XTDB to Datomic
- Update database layer descriptions from XTDB to Datomic
- Simplify configuration documentation (remove XTDB-specific connection details)
- Update data model to use Datomic entity/attribute naming conventions
- Update notes section to reference Datalog instead of XTQL
- Remove XTDB dependencies and test fixtures from test suite
- Simplify test utilities to work without XTDB test nodes
2026-03-12 10:31:44 +01:00

5 KiB

CLAUDE.md

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

Project Overview

A REST API backend for managing code snippets, written in Clojure using Datomic for data storage. The API provides endpoints for creating, reading, editing, and deleting snippets, with support for tagging and slug-based lookup.

Related Projects:

Development Commands

Run Development Server

clojure -M -m snippets.main

Starts the API server on the configured host/port (default: localhost:8080). The REPL can be used to develop with the server:

; Start server in background from REPL:
(def server (jetty/run-jetty #'app {:port 3000 :join? false}))
; Stop server:
(.stop server)

Build Uberjar

clojure -T:build uber

Creates a standalone JAR file at target/snippets-standalone.jar that includes all dependencies.

REPL Commands

Common REPL operations:

; Pretty-print data structures
(clojure.pprint/pprint {:name "Alice" :age 30})

; Require a namespace (fresh import)
(require 'clojure.string)
(require '[clojure.string :as str])
(require 'my.namespace :reload)

; List namespace contents
(dir clojure.string)

; Switch namespaces
(in-ns 'my.namespace)
(in-ns 'user)

Linting

The project uses clj-kondo for static analysis. Configuration is in .clj-kondo/config.edn. Linting is integrated into most IDEs via LSP.

Code Architecture

Directory Structure

  • src/snippets/infra/ - Infrastructure layer (HTTP API, database, configuration)
    • api.clj - HTTP routing and handlers using reitit
    • db.clj - Datomic queries and transactions
    • config.clj - Configuration loading (config.edn + environment variables)
  • src/snippets/use_cases/ - Business logic layer
    • view.clj - Query/read operations, includes serialization for JSON output
    • create.clj - Create snippets
    • edit.clj - Patch snippets with validation
    • delete.clj - Delete snippets
  • test/ - Test suite

Architecture Pattern

Clean separation between layers:

  1. Infrastructure (infra/): Handles external concerns

    • HTTP/REST via reitit + ring
    • Datomic database client and queries
    • Environment configuration
  2. Use Cases: Business logic implementing application features

    • Each use case is a module with focused responsibility
    • Calls infrastructure layer (infra.db, infra.config) as needed
    • Performs serialization/transformation for API responses
  3. Main Entry Point (main.clj): Minimal bootstrap that runs the API server

Data Model

Snippets are Datomic entities with:

  • :snippet/title - Snippet title
  • :snippet/slug - URL-friendly identifier for query lookups
  • :snippet/markdown - Snippet content in markdown format
  • :snippet/tags - Vector of strings for categorization
  • :snippet/pub-date - Date object (serialized to ISO-8601 strings for API responses)

API Endpoints

All routes under /api:

  • GET /api/ping - Health check
  • GET /api/snippets - List snippets (with optional limit and skip query params)
  • GET /api/snippet?id=<id> - Get snippet by UUID
  • GET /api/snippet-by-slug?slug=<slug> - Get snippet by slug
  • POST /api/snippet - Create snippet
  • PATCH /api/snippet?id=<id> - Edit snippet (patches are validated against schema)
  • DELETE /api/snippet?id=<id> - Delete snippet
  • GET /api/tags - List all tags with counts
  • GET /api/tag?tag=<tag> - Get snippets by tag

Key Dependencies

  • reitit (0.9.1) - HTTP routing and coercion
  • ring (1.13.0) - HTTP server (jetty adapter)
  • Datomic - Database with ACID transactions and query capabilities
  • malli (0.18.0) - Schema validation and generation
  • muuntaja (0.6.11) - JSON/EDN encoding/decoding
  • telemere (1.0.0) - Structured logging
  • environ (1.2.0) - Environment variable loading

Configuration

Configuration comes from config.edn with environment variable overrides:

{:jetty {:host "localhost" :port 8080}
 :datomic {}}

Environment variables can override specific values:

  • HOST - Jetty host
  • PORT - Jetty port (parsed as integer)

See infra/config.clj for how overrides are applied.

Testing

Run the test suite:

clojure -M:test:clojure.test/run

Or from REPL:

(clojure.test/run-tests 'snippets-test)

The test namespace snippets-test includes:

  • Basic arithmetic tests
  • Datomic integration tests
  • HTML rendering tests using rum

Deployment

Docker image built and pushed to AWS ECR via build.sh:

./build.sh

Requires AWS CLI configured with personal profile and permission to push to ECR repository.

Notes

  • Datomic queries use Datalog query language
  • Date serialization happens in view.clj - pub-date objects are converted to ISO-8601 strings for JSON responses
  • Patch validation is strict - only specific fields can be updated
  • UUIDs used for snippet IDs; generated client-side on creation