mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-05-15 13:23:13 +08:00
* feat: update tinystruct-patterns skill with comprehensive expert knowledge * Update skills/tinystruct-patterns/SKILL.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update skills/tinystruct-patterns/SKILL.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Update skills/tinystruct-patterns/references/database.md Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update testing.md * Update database.md --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
204 lines
8.8 KiB
Markdown
204 lines
8.8 KiB
Markdown
---
|
||
name: tinystruct-patterns
|
||
description: Expert guidance for developing with the tinystruct Java framework. Use when working on the tinystruct codebase or any project built on tinystruct — including creating Application classes, @Action-mapped routes, unit tests, ActionRegistry, HTTP/CLI dual-mode handling, the built-in HTTP server, the event system, JSON with Builder/Builders, database persistence with AbstractData, POJO generation, Server-Sent Events (SSE), file uploads, and outbound HTTP networking.
|
||
origin: ECC
|
||
---
|
||
|
||
# tinystruct Development Patterns
|
||
|
||
Architecture and implementation patterns for building modules with the **tinystruct** Java framework – a lightweight, high-performance framework that treats CLI and HTTP as equal citizens, requiring no `main()` method and minimal configuration.
|
||
|
||
## Core Principle
|
||
|
||
**CLI and HTTP are equal citizens.** Every method annotated with `@Action` should ideally be runnable from both a terminal and a web browser without modification. This "dual-mode" capability is the core design philosophy of tinystruct.
|
||
|
||
## When to Activate
|
||
|
||
### When to Use
|
||
|
||
- Creating new `Application` modules by extending `AbstractApplication`.
|
||
- Defining routes and command-line actions using `@Action`.
|
||
- Handling per-request state via `Context`.
|
||
- Performing JSON serialization using the native `Builder` and `Builders` components.
|
||
- Working with database persistence via `AbstractData` POJOs.
|
||
- Generating POJOs from database tables using the `generate` command.
|
||
- Implementing Server-Sent Events (SSE) for real-time push.
|
||
- Handling file uploads via multipart data.
|
||
- Making outbound HTTP requests with `URLRequest` and `HTTPHandler`.
|
||
- Configuring database connections or system settings in `application.properties`.
|
||
- Debugging routing conflicts (Actions) or CLI argument parsing.
|
||
|
||
## How It Works
|
||
|
||
The tinystruct framework treats any method annotated with `@Action` as a routable endpoint for both terminal and web environments. Applications are created by extending `AbstractApplication`, which provides core lifecycle hooks like `init()` and access to the request `Context`.
|
||
|
||
Routing is handled by the `ActionRegistry`, which automatically maps path segments to method arguments and injects dependencies. For data-only services, the native `Builder` and `Builders` components should be used for JSON serialization to maintain a zero-dependency footprint. The database layer uses `AbstractData` POJOs paired with XML mapping files for CRUD operations without external ORM libraries.
|
||
|
||
## Examples
|
||
|
||
### Basic Application (MyService)
|
||
```java
|
||
public class MyService extends AbstractApplication {
|
||
@Override
|
||
public void init() {
|
||
this.setTemplateRequired(false); // Disable .view lookup for data/API apps
|
||
}
|
||
|
||
@Override public String version() { return "1.0.0"; }
|
||
|
||
@Action("greet")
|
||
public String greet() {
|
||
return "Hello from tinystruct!";
|
||
}
|
||
|
||
// Path parameter: GET /?q=greet/James OR bin/dispatcher greet/James
|
||
@Action("greet")
|
||
public String greet(String name) {
|
||
return "Hello, " + name + "!";
|
||
}
|
||
}
|
||
```
|
||
|
||
### HTTP Mode Disambiguation (login)
|
||
```java
|
||
@Action(value = "login", mode = Mode.HTTP_POST)
|
||
public String doLogin(Request<?, ?> request) throws ApplicationException {
|
||
request.getSession().setAttribute("userId", "42");
|
||
return "Logged in";
|
||
}
|
||
```
|
||
|
||
### Native JSON Data Handling (Builder + Builders)
|
||
```java
|
||
import org.tinystruct.data.component.Builder;
|
||
import org.tinystruct.data.component.Builders;
|
||
|
||
@Action("api/data")
|
||
public String getData() throws ApplicationException {
|
||
Builders dataList = new Builders();
|
||
Builder item = new Builder();
|
||
item.put("id", 1);
|
||
item.put("name", "James");
|
||
dataList.add(item);
|
||
|
||
Builder response = new Builder();
|
||
response.put("status", "success");
|
||
response.put("data", dataList);
|
||
return response.toString(); // {"status":"success","data":[{"id":1,"name":"James"}]}
|
||
}
|
||
```
|
||
|
||
### SSE (Server-Sent Events)
|
||
```java
|
||
import org.tinystruct.http.SSEPushManager;
|
||
|
||
@Action("sse/connect")
|
||
public String connect() {
|
||
return "{\"type\":\"connect\",\"message\":\"Connected to SSE\"}";
|
||
}
|
||
|
||
// Push to a specific client
|
||
String sessionId = getContext().getId();
|
||
Builder msg = new Builder();
|
||
msg.put("text", "Hello, user!");
|
||
SSEPushManager.getInstance().push(sessionId, msg);
|
||
|
||
// Broadcast to all
|
||
// Broadcast to all
|
||
SSEPushManager.getInstance().broadcast(msg);
|
||
```
|
||
|
||
### File Upload
|
||
```java
|
||
import org.tinystruct.data.FileEntity;
|
||
|
||
@Action(value = "upload", mode = Mode.HTTP_POST)
|
||
public String upload(Request<?, ?> request) throws ApplicationException {
|
||
List<FileEntity> files = request.getAttachments();
|
||
if (files != null) {
|
||
for (FileEntity file : files) {
|
||
System.out.println("Uploaded: " + file.getFilename());
|
||
}
|
||
}
|
||
return "Upload OK";
|
||
}
|
||
```
|
||
|
||
## Configuration
|
||
|
||
Settings are managed in `src/main/resources/application.properties`.
|
||
|
||
```properties
|
||
# Database
|
||
driver=org.h2.Driver
|
||
database.url=jdbc:h2:~/mydb
|
||
database.user=sa
|
||
database.password=
|
||
|
||
# Server
|
||
default.home.page=hello
|
||
server.port=8080
|
||
|
||
# Locale
|
||
default.language=en_US
|
||
|
||
# Session (Redis for clustered environments)
|
||
# default.session.repository=org.tinystruct.http.RedisSessionRepository
|
||
# redis.host=127.0.0.1
|
||
# redis.port=6379
|
||
```
|
||
|
||
Access config values in your application:
|
||
```java
|
||
String port = this.getConfiguration("server.port");
|
||
```
|
||
|
||
## Red Flags & Anti-patterns
|
||
|
||
| Symptom | Correct Pattern |
|
||
|---|---|
|
||
| Importing `com.google.gson` or `com.fasterxml.jackson` | Use `org.tinystruct.data.component.Builder` / `Builders`. |
|
||
| Using `List<Builder>` for JSON arrays | Use `Builders` to avoid generic type erasure issues. |
|
||
| `ApplicationRuntimeException: template not found` | Call `setTemplateRequired(false)` in `init()` for API-only apps. |
|
||
| Annotating `private` methods with `@Action` | Actions must be `public` to be registered by the framework. |
|
||
| Hardcoding `main(String[] args)` in apps | Use `bin/dispatcher` as the entry point for all modules. |
|
||
| Manual `ActionRegistry` registration | Prefer the `@Action` annotation for automatic discovery. |
|
||
| Action not found at runtime | Ensure class is imported via `--import` or listed in `application.properties`. |
|
||
| CLI arg not visible | Pass with `--key value`; access via `getContext().getAttribute("--key")`. |
|
||
| Two methods same path, wrong one fires | Set explicit `mode` (e.g., `HTTP_GET` vs `HTTP_POST`) to disambiguate. |
|
||
|
||
## Best Practices
|
||
|
||
1. **Granular Applications**: Break logic into smaller, focused applications rather than one monolithic class.
|
||
2. **Setup in `init()`**: Leverage `init()` for setup (config, DB) rather than the constructor. Do NOT call `setAction()` — use `@Action` annotation.
|
||
3. **Mode Awareness**: Use the `Mode` parameter in `@Action` to restrict sensitive operations to `CLI` only or specific HTTP methods.
|
||
4. **Context over Params**: For optional CLI flags, use `getContext().getAttribute("--flag")` rather than adding parameters to the method signature.
|
||
5. **Asynchronous Events**: For heavy tasks triggered by events, use `CompletableFuture.runAsync()` inside the event handler.
|
||
|
||
## Technical Reference
|
||
|
||
Detailed guides are available in the `references/` directory:
|
||
|
||
- [Architecture & Config](references/architecture.md) — Abstractions, Package Map, Properties
|
||
- [Routing & @Action](references/routing.md) — Annotation details, Modes, Parameters
|
||
- [Data Handling](references/data-handling.md) — Builder, Builders, JSON serialization & parsing
|
||
- [Database Persistence](references/database.md) — AbstractData POJOs, CRUD, mapping XML, POJO generation
|
||
- [System & Usage](references/system-usage.md) — Context, Sessions, SSE, File Uploads, Events, Networking
|
||
- [Testing Patterns](references/testing.md) — JUnit 5 unit and HTTP integration testing
|
||
|
||
## Reference Source Files (Internal)
|
||
|
||
- `src/main/java/org/tinystruct/AbstractApplication.java` — Core base class with lifecycle hooks
|
||
- `src/main/java/org/tinystruct/system/annotation/Action.java` — Annotation & Modes
|
||
- `src/main/java/org/tinystruct/application/ActionRegistry.java` — Routing Engine
|
||
- `src/main/java/org/tinystruct/data/component/Builder.java` — JSON object serializer
|
||
- `src/main/java/org/tinystruct/data/component/Builders.java` — JSON array serializer
|
||
- `src/main/java/org/tinystruct/data/component/AbstractData.java` — Base POJO class with CRUD
|
||
- `src/main/java/org/tinystruct/data/Mapping.java` — Mapping XML parser
|
||
- `src/main/java/org/tinystruct/data/tools/MySQLGenerator.java` — POJO generator reference
|
||
- `src/main/java/org/tinystruct/data/component/FieldType.java` — SQL-to-Java type mappings
|
||
- `src/main/java/org/tinystruct/data/component/Condition.java` — Fluent SQL query builder
|
||
- `src/main/java/org/tinystruct/http/SSEPushManager.java` — SSE connection management
|
||
- `src/test/java/org/tinystruct/application/ActionRegistryTest.java` — Registry test examples
|
||
- `src/test/java/org/tinystruct/system/HttpServerHttpModeTest.java` — HTTP integration test patterns
|