← スキル一覧に戻る

cartridge
by karloscodes
⭐ 1🍴 0📅 2026年1月16日
SKILL.md
name: cartridge description: Use when working with Go web applications using the cartridge framework - covers Application, Server, Context, SQLite, Inertia, Flash, Cache, and middleware
Cartridge Framework
Minimal, opinionated Go web framework built on Fiber. Designed for solo maintainability.
Package Structure
github.com/karloscodes/cartridge
├── application.go # App bootstrap, lifecycle, graceful shutdown
├── server.go # HTTP server, routing, middleware mounting
├── context.go # Request context with DB, Logger, Config
├── session.go # Session management
├── cache/ # Cache with memory and database stores
├── flash/ # Flash messages for PRG pattern
├── inertia/ # Inertia.js adapter for React SSR
├── sqlite/ # SQLite manager with WAL, transactions
├── middleware/ # Concurrency, helmet, rate limiter, recovery
├── testsupport/ # Test helpers for DB and server
└── config/ # Base config interface
Core Concepts
Application Bootstrap
app, err := cartridge.NewApplication(cartridge.ApplicationOptions{
Config: cfg,
Logger: logger,
DBManager: dbManager,
RouteMountFunc: mountRoutes,
BackgroundWorkers: []cartridge.BackgroundWorker{jobsManager},
})
app.Run() // Blocks, handles signals, graceful shutdown
Handler Signature
Single signature for all handlers:
func(ctx *cartridge.Context) error
Context provides:
ctx.Ctx- embedded*fiber.Ctxfor all HTTP methodsctx.DB()- GORM database connectionctx.Logger- structured loggerctx.Config- runtime config
Route Configuration
func mountRoutes(srv *cartridge.Server) {
// Basic route
srv.Get("/", homeHandler)
// With config
srv.Post("/api/items", createHandler, &cartridge.RouteConfig{
WriteConcurrency: true, // SQLite write queue
EnableCORS: true, // CORS headers
EnableCSRF: cartridge.Bool(true),
EnableSecFetchSite: cartridge.Bool(false),
RateLimit: 100, // requests per minute
})
// Route groups
admin := srv.Group("/admin", authMiddleware)
admin.Get("/dashboard", dashboardHandler)
}
SQLite Package
import "github.com/karloscodes/cartridge/sqlite"
// Manager setup
cfg := sqlite.Config{
Path: "data.db",
MaxOpenConns: 1,
MaxIdleConns: 1,
EnableWAL: true,
TxImmediate: true,
BusyTimeout: 5000,
Logger: logger,
}
manager := sqlite.NewManager(cfg)
db, err := manager.Connect()
// Transactions with PerformWrite (serialized writes)
err := sqlite.PerformWrite(db, func(tx *gorm.DB) error {
return tx.Create(&record).Error
})
// WAL checkpoint
manager.CheckpointWAL("FULL")
Inertia.js Integration
For React SSR with server-side props:
import "github.com/karloscodes/cartridge/inertia"
func dashboardHandler(ctx *cartridge.Context) error {
return inertia.RenderPage(ctx.Ctx, "Dashboard", inertia.Props{
"user": currentUser,
"metrics": dashboardMetrics,
})
}
Frontend receives props via window.__PAGE_DATA__.
Flash Messages
PRG (Post-Redirect-Get) pattern:
import "github.com/karloscodes/cartridge/flash"
// Set flash before redirect
flash.SetFlash(ctx.Ctx, "success", "Item created")
return ctx.Redirect("/items", fiber.StatusFound)
// Get flash in next request (auto-clears)
msg := flash.GetFlash(ctx.Ctx, "success")
Cache
import "github.com/karloscodes/cartridge/cache"
// Memory cache
store := cache.NewMemoryStore()
// Database cache (persisted)
store := cache.NewDatabaseStore(db)
// Usage
store.Set("key", value, 5*time.Minute)
value, found := store.Get("key")
store.Delete("key")
Session Management
sessionMgr := cartridge.NewSessionManager(cartridge.SessionConfig{
CookieName: "_session",
Secret: cfg.GetPrivateKey(),
Expiration: 24 * time.Hour,
SecureCookie: cfg.IsProduction(),
})
srv.SetSessionManager(sessionMgr)
// In handler
session := ctx.Session()
session.Set("user_id", userID)
session.Save()
Middleware
Built-in (auto-applied)
- Recovery (panic handling)
- Request logging
- Compression
Per-route
&cartridge.RouteConfig{
WriteConcurrency: true, // SQLite write serialization
EnableCORS: true, // CORS headers
EnableCSRF: cartridge.Bool(true),
EnableSecFetchSite: cartridge.Bool(true),
RateLimit: 100, // per minute
}
Custom middleware
import cartridgemiddleware "github.com/karloscodes/cartridge/middleware"
// Sec-Fetch-Site validation
cartridgemiddleware.SecFetchSite(cartridgemiddleware.SecFetchConfig{
AllowedModes: []string{"navigate", "same-origin"},
})
Test Support
import "github.com/karloscodes/cartridge/testsupport"
func TestHandler(t *testing.T) {
// Setup test DB
db := testsupport.SetupTestDB(t)
// Setup test server
srv := testsupport.NewTestServer(t, db, mountRoutes)
// Make request
resp := srv.Get("/api/items")
assert.Equal(t, 200, resp.StatusCode)
}
Patterns
Handler with DB write
func createItem(ctx *cartridge.Context) error {
var input CreateItemInput
if err := ctx.BodyParser(&input); err != nil {
return ctx.Status(400).JSON(fiber.Map{"error": "invalid input"})
}
item := &Item{Name: input.Name}
if err := sqlite.PerformWrite(ctx.DB(), func(tx *gorm.DB) error {
return tx.Create(item).Error
}); err != nil {
return ctx.Status(500).JSON(fiber.Map{"error": "failed to create"})
}
return ctx.JSON(item)
}
PRG form submission
func handleForm(ctx *cartridge.Context) error {
// Process form...
if err != nil {
flash.SetFlash(ctx.Ctx, "error", err.Error())
return ctx.Redirect("/form", fiber.StatusFound)
}
flash.SetFlash(ctx.Ctx, "success", "Saved!")
return ctx.Redirect("/form", fiber.StatusFound)
}
Inertia page with flash
func showPage(ctx *cartridge.Context) error {
return inertia.RenderPage(ctx.Ctx, "Page", inertia.Props{
"data": data,
"flash": flash.GetAllFlash(ctx.Ctx),
})
}
Import Paths
import (
"github.com/karloscodes/cartridge"
"github.com/karloscodes/cartridge/cache"
"github.com/karloscodes/cartridge/flash"
"github.com/karloscodes/cartridge/inertia"
"github.com/karloscodes/cartridge/sqlite"
"github.com/karloscodes/cartridge/testsupport"
cartridgemiddleware "github.com/karloscodes/cartridge/middleware"
)
スコア
総合スコア
50/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
○LICENSE
ライセンスが設定されている
0/10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です