This service was generated from the AsterForge aster-service template.
- AsterForge project: AsterCommunity/AsterForge
- AsterForge documentation: forge.astercosm.com
- AsterForge Rust API documentation: forge.astercosm.com/crates/rustdoc
- New project integration guide: forge.astercosm.com/guide/new-project-integration
cargo check
cargo runDebug and test builds use an isolated frontend fallback under Cargo's OUT_DIR when
frontend-panel/dist is missing, so a backend-only build does not write generated assets into the
source tree. Release builds require a real frontend bundle:
cd frontend-panel
bun install --frozen-lockfile
bun run build
cd ..
cargo build --releaseThe build script accepts an explicit single-line ASTER_BUILD_TIME; when it is unset, the script
uses the current UTC time. Embedded assets are selected through the build-time
ASTER_FRONTEND_DIST_DIR value rather than a source-tree-only path.
The generated service starts an Axum HTTP server and registers the standard Forge runtime components:
- HTTP service component.
- Background task shutdown component.
- Mail outbox shutdown component.
- Audit lifecycle component.
- Database shutdown and health component.
- Migration crate with Forge-owned infrastructure tables.
- Optional Prometheus metrics export when the
metricsfeature is enabled. - Debug allocation tracking by default and jemalloc feature flags for production tuning.
- Debug OpenAPI document and Swagger UI when the
openapifeature is enabled.
Runtime display names use Cargo package metadata. Rename the generated package in Cargo.toml
when the service name should change; the template reads env!("CARGO_PKG_NAME") instead of
keeping a separate service-name placeholder.
The generated rust-toolchain.toml installs Rust 1.95 with rustfmt, clippy, and
llvm-tools-preview. The development profile keeps workspace code at O0 with high codegen
parallelism while compiling third-party dependencies at O1, matching AsterDrive's local feedback
profile.
The generated service looks for static configuration at data/config.toml by default. Override the
path with ASTER_CONFIG=/path/to/config.toml.
If no configuration file exists, the service writes data/config.toml with the defaults selected
during cargo generate, then loads that file. Copy or edit config.example.toml when the service
needs deployment-specific values.
The default data layout matches AsterDrive and AsterYggdrasil:
data/config.tomldata/aster_gate.dbdata/.tmp
Startup creates the parent directories for the configured temp directory and SQLite database. It
also creates the parent directory for logging.file when file logging is configured.
Relative filesystem paths and relative sqlite:// database paths in data/config.toml are
resolved from the configuration file directory. For example, sqlite://service.db?mode=rwc in
data/config.toml points to data/service.db.
The generator only asks for values that are useful at project creation time:
package_description: Cargo package and container image description.server_port: Local HTTP bind port.
Server host/port/temp dir, database pool/retry settings, cache, config sync, and logging use
conservative defaults in the generated configuration. Override them in data/config.toml or with
ASTER__... environment variables when deploying.
Keep these in this product repository:
- Product API routes and DTOs.
- Product permissions and user-facing error mapping.
- Product entities and migrations.
- Product audit action/detail/presentation types.
- Product task kind, payload, result, and execution body.
- Product mail payloads, template rendering, URLs, and audit hooks.
Use Forge for reusable mechanics:
AsterRuntimelifecycle and component graph.- Database handles, migration schema builders, shared infrastructure stores, and shutdown.
- Background task runtime/shutdown mechanics.
- Mail outbox dispatch and DB-backed state machine.
- Audit lifecycle component and shared audit log store.
- Cache/config/middleware/metrics/panic helpers.
The generated workspace includes a migration crate. The first migration creates Forge-owned
infrastructure tables for runtime leases, scheduled tasks, system config, mail outbox, and audit
logs. Product tables should be added as new migration modules in that crate.
OpenAPI generation follows the same debug-only pattern used by Aster services:
cargo run --features openapi
cargo test --features openapi --test generate_openapiWhen enabled in a debug build, the service exposes:
/api-docs/openapi.json/swagger-ui/
The OpenAPI generation test writes the tracked frontend-panel/generated/openapi.json. Refresh
both tracked artifacts after API changes:
cargo test --features openapi --test generate_openapi
cd frontend-panel
bun run generate-apiThe generated SDK is written to frontend-panel/src/types/api.generated.ts; application code
imports the stable wrapper from frontend-panel/src/types/api.ts.
Add product route annotations with aster_forge_api_docs_macros::path(...), then register those
handlers and schemas in src/api/openapi.rs. Release builds do not expand the route annotations
unless the product intentionally changes that policy.
Prometheus metrics are available when the metrics feature is enabled:
cargo run --features metricsThe service then exposes /health/metrics through the Axum adapter in Forge. Forge records
low-cardinality HTTP, database, health, background task, external-operation, allocator heap,
process RSS, CPU, and uptime metrics through shared recorder traits.
Allocator behavior follows the Aster service pattern:
- Debug builds without
jemallocuseaster_forge_alloc::TrackingAlloc. --features jemallocenablestikv-jemallocator.--features jemalloc-statsenables jemalloc allocator stats.--features jemalloc-profilingenables jemalloc profiling support.
The template exposes:
/api/v1/*: versioned product API scope. Unknown API paths return a JSONendpoint_not_foundresponse instead of the frontend SPA fallback./health: lightweight liveness response./health/ready: database and cache readiness check./health/metrics: Prometheus text export when themetricsfeature is enabled.
The generated project includes:
.github/workflows/rust.yml: AsterDrive-aligned format/clippy, OpenAPI and TypeScript SDK drift, coverage summary/artifact, and PostgreSQL/MySQL integration jobs..github/workflows/audit.yml: dependency-change, scheduled, and manualcargo audit -D warnings..github/workflows/docker-image.yml: GHCR image publishing for default andmetricsvariants.
The backend integration matrix uses reusable testcontainers and runs the Forge foundation
migration against PostgreSQL and MySQL. Docker must be available when running those tests locally
with ASTER_TEST_DATABASE_BACKEND=postgres or mysql.
Build the container image with:
docker build -t aster_gate .By default the image builds with CARGO_FEATURES=metrics, matching the AsterDrive and
AsterYggdrasil container profile. Override it when needed:
docker build --build-arg CARGO_FEATURES=metrics,openapi -t aster_gate .Run the generated compose file:
docker compose up --buildMount /data for persistent runtime files. The image sets:
ASTER__SERVER__HOST=0.0.0.0
The image healthcheck probes /health/ready.
The template depends on the AsterForge project through Git:
aster_forge_runtime = { git = "https://github.com/AsterCommunity/AsterForge", package = "aster_forge_runtime" }When working on Forge and a generated product on the same machine, temporarily replace those Git
dependencies with local path = "../AsterForge/crates/..." entries or a [patch] section in the
generated product. Keep the generated product's public shape the same: product code should call
Forge APIs directly unless an adapter adds product error mapping, config injection, audit, metrics,
or permissions.