Skip to content

Commit 7a94ae9

Browse files
committed
Merge branch 'main' of github.com:devforth/adminforth into update-docs-fot-the-2fa
AdminForth/1304/plugins-frontend-api.-improve- AdminForth/1304/plugins-frontend-api.-improve-
2 parents 0db3bcd + 445b239 commit 7a94ae9

335 files changed

Lines changed: 20617 additions & 16270 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Deploy Documentation
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'adminforth/documentation/**'
9+
- '.github/workflows/deploy_documentation.yaml'
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
defaults:
15+
run:
16+
working-directory: adminforth
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
- name: Install pnpm
21+
uses: pnpm/action-setup@v4
22+
with:
23+
version: 9
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '20'
28+
cache: 'pnpm'
29+
cache-dependency-path: adminforth/pnpm-lock.yaml
30+
31+
- name: Configure Git
32+
run: |
33+
git config --global user.name "${{ github.actor }}"
34+
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
35+
36+
- name: Install dependencies
37+
run: |
38+
pnpm i
39+
cd documentation
40+
npm ci
41+
42+
- name: Build and deploy docs
43+
run: GIT_USER=${{ github.actor }} GIT_PASS=${{ secrets.DOCUSAURUS_DEPLOY_KEY }} pnpm rollout-doc

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ plugins/*
33
!plugins/README.md
44
adapters/*
55
!adapters/README.md
6-
background-jobs-dbs
6+
background-jobs-dbs
7+
tests/jest_tests/db/

AGENTS.md

Lines changed: 229 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,229 @@
1-
Follow SOLID principles
2-
Use DRY and avoid duplication
3-
Keep the code KISS unless complexity is required
4-
Avoid unnecessary abstractions.
5-
Cover edge cases and clear error handling
1+
2+
# AGENTS.md
3+
4+
## Package manager
5+
6+
All packages and projects in this repo use `pnpm` and not `npm`.
7+
Howeverer internally (e.g. in `codeInjector`) adminforth still supports both `npm` and `pnpm` style install commands, so users of framework itself can use it with either package manager. But in all dev demo/live demo, plugins, adapters, and documentation, we use `pnpm` as the standard.
8+
9+
## Package names rules
10+
11+
12+
All adapters and plugins always have `@adminforth/` prefix in their package name, followed by short lowercase kebab-case plugin/adpater slug.
13+
14+
Every plugin has at least one Docusaurus docs page, which should use the path `/docs/tutorial/Plugins/<plugin-slug>/`.
15+
16+
Same for adapters, but with `/docs/tutorial/Adapters/<adapter-slug>/` path.
17+
18+
Page names in docusarus should be human readabale. We should not use `AuditLog` but instead we should have `Audit Log` via whitespace.
19+
20+
21+
## General engineering rules
22+
23+
Write code as if the system contracts are already defined and trusted.
24+
25+
Do not add defensive checks “just in case” when the contract, type, schema, backend response, or controlled internal API already guarantees the shape of the data.
26+
27+
Prefer simplicity, clarity, and consistency over paranoia.
28+
29+
Follow these principles strictly:
30+
31+
- DRY
32+
- SOLID
33+
- YAGNI
34+
- Keep code minimal
35+
- Trust typed contracts
36+
- Avoid duplicate validation
37+
- Avoid speculative fallback logic
38+
- Avoid inline regex literals when reused or non-trivial
39+
40+
---
41+
42+
## Trust the contract
43+
44+
If backend and frontend are part of the same system, and the backend explicitly guarantees a response shape, do **not** re-validate every field on the frontend.
45+
46+
Bad:
47+
- backend returns a strict object
48+
- frontend then checks every field for `undefined`, wrong type, empty string, wrong enum, etc.
49+
- frontend adds fallback branches for impossible states
50+
51+
Good:
52+
- backend owns validation
53+
- shared types or schemas define the contract
54+
- frontend consumes the contract directly
55+
- frontend only handles real UI states, not imaginary protocol corruption
56+
57+
Do not treat trusted internal responses as untrusted external input.
58+
59+
Only add extra runtime validation when:
60+
- data comes from a truly external/untrusted source
61+
- the contract is unknown or unstable
62+
- there is an explicit requirement for hardening
63+
- security boundaries require validation
64+
- corrupted legacy data is known to exist in production
65+
66+
If none of the above is true, do not add redundant guards.
67+
68+
---
69+
70+
## No duplicate validation
71+
72+
Validation must live in one clear place.
73+
74+
Prefer this order:
75+
1. Boundary validation
76+
2. Domain validation
77+
3. UI rendering without re-checking the same invariants
78+
79+
Examples:
80+
- Validate request payload on the backend boundary
81+
- Validate forms at form/input level
82+
- Validate DB input before persistence if needed
83+
- Do not re-check the same rule again deeper in the stack unless there is a real new boundary
84+
85+
If a field is already guaranteed by type/schema/backend, do not validate it again in consumers.
86+
87+
---
88+
89+
## Frontend rules
90+
91+
When rendering data from a trusted backend:
92+
- do not check every property manually
93+
- do not write `if (!obj || !obj.a || !obj.b || !obj.c)` chains for guaranteed objects
94+
- do not silently swallow impossible states
95+
- do not invent fallback values for required fields unless product requirements explicitly ask for fallback UI
96+
97+
Prefer:
98+
- strong TypeScript types
99+
- narrow, explicit UI states
100+
- a small number of meaningful guards at actual boundaries
101+
102+
Allowed:
103+
- loading state
104+
- not-found state
105+
- permission-denied state
106+
- explicitly documented optional fields
107+
108+
Not allowed:
109+
- repetitive property-by-property paranoia checks for required response fields
110+
111+
---
112+
113+
## Backend rules
114+
115+
Backend should enforce the contract once, clearly and centrally.
116+
117+
- Validate incoming external input at the boundary
118+
- Normalize data once
119+
- Return stable, typed responses
120+
- Do not scatter the same checks across controllers, services, and callers
121+
- Do not add branches for impossible states without evidence
122+
123+
When a response format is defined, keep it strict and predictable so consumers do not need defensive coding.
124+
125+
---
126+
127+
## Regex rules
128+
129+
Do not inline non-trivial regexes directly inside business logic.
130+
131+
Bad:
132+
- inline regex literals scattered through the codebase
133+
- repeating the same regex multiple times
134+
- unreadable regex embedded inside conditions
135+
136+
Good:
137+
- define regex once as a named constant
138+
- place reusable regexes in a dedicated constants/module file
139+
- give regexes semantic names
140+
- compile once when appropriate
141+
142+
Example:
143+
- `const EMAIL_RE = /.../`
144+
- `const SLUG_RE = /.../`
145+
- `const STRIP_HTML_RE = /.../g`
146+
147+
If regex is used more than once or is not instantly obvious, extract it.
148+
149+
---
150+
151+
## No speculative coding
152+
153+
Do not add code for hypothetical scenarios unless they are documented requirements or known production realities.
154+
155+
Avoid:
156+
- “in case backend changes”
157+
- “in case this field comes null someday”
158+
- “in case this enum gets other values”
159+
- “in case this internal method returns something unexpected”
160+
161+
If such a risk is real, document it and solve it at the right boundary, not everywhere.
162+
163+
---
164+
165+
## Error handling
166+
167+
Error handling must be intentional, not reflexive.
168+
169+
Handle:
170+
- real network failures
171+
- documented optionality
172+
- known domain errors
173+
- permission/auth errors
174+
- user-caused invalid input
175+
- external system failures
176+
177+
Do not handle:
178+
- impossible states already excluded by the contract
179+
- contradictions to compile-time types without evidence
180+
- redundant field-level checks for trusted internal data
181+
182+
For impossible states, prefer failing loudly in development rather than hiding the issue with fallback logic.
183+
184+
---
185+
186+
## Code review rules for agents
187+
188+
Before writing extra guards, ask:
189+
190+
1. Is this input external and untrusted?
191+
2. Is this invariant already guaranteed by types/schema/backend?
192+
3. Am I repeating validation that already exists elsewhere?
193+
4. Is this a real production case or just imagination?
194+
5. Would this code make the system clearer, or only noisier?
195+
196+
If the invariant is already guaranteed, do not add the guard.
197+
198+
---
199+
200+
## Preferred style
201+
202+
Prefer:
203+
- shared types
204+
- schema-driven boundaries
205+
- single-source-of-truth validation
206+
- concise functions
207+
- explicit contracts
208+
- named helpers/constants
209+
- reusable compiled regex constants
210+
211+
Avoid:
212+
- defensive clutter
213+
- repeated null/undefined chains for required fields
214+
- duplicated business rules
215+
- inline complicated regex
216+
- fallback-on-fallback logic
217+
- broad “safety” code without a concrete reason
218+
219+
---
220+
221+
## Decision rule
222+
223+
When choosing between:
224+
- trusting a well-defined internal contract
225+
- or adding more defensive checks
226+
227+
choose trusting the contract, unless there is a clear boundary, documented risk, or real evidence that extra validation is needed.
228+
229+
Less code, fewer duplicate checks, clearer ownership.

README.md

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
# AdminForth - free powerfull Node.js admin panel framework on Vue & Tailwind
1+
# AdminForth - powerfull Agent-first Typescript admin panel framework
22

33

44
<a href="https://adminforth.dev"><img src="https://img.shields.io/badge/website-adminforth.dev-blue" style="height:24px"/></a> <a href="https://adminforth.dev"><img src="https://img.shields.io/npm/dw/adminforth" style="height:24px"/></a> <a href="https://devforth.io"><img src="https://raw.githubusercontent.com/devforth/OnLogs/e97944fffc24fec0ce2347b205c9bda3be8de5c5/.assets/df_powered_by.svg" style="height:28px"/></a>
55

66
[![Ask AI](http://tluma.ai/badge)](http://tluma.ai/ask-ai/devforth/adminforth)
77

8-
* [Try live demo](https://demo.adminforth.dev/) (Read-only mode)
8+
* [Try live demo](https://demo.adminforth.dev/)
9+
10+
* [YouTube video: build agentic admin panel in a minutes](https://www.youtube.com/watch?v=4tB8uzY__uk)
911

1012
* [Hello world in 5 minutes](https://adminforth.dev/docs/tutorial/gettingStarted) with AdminForth
1113

@@ -14,10 +16,11 @@
1416
<br/>
1517

1618
<div align="center">
17-
<img src="https://github.com/user-attachments/assets/e643caad-1daa-4085-b125-cc940557a2ec"
18-
alt="AdminForth Dashboard" width="90%">
19+
<img src="https://github.com/user-attachments/assets/775c527d-65c3-4d9c-bb0c-3692462f2818"
20+
alt="AdminForth Agent" width="90%">
1921
</div>
2022

23+
2124
<br/>
2225

2326
Why AdminForth:
@@ -34,32 +37,43 @@ Why AdminForth:
3437

3538
## Project initialisation
3639

37-
```
38-
mkdir myadmin && cd myadmin
40+
To create an AdminForth project, run:
41+
42+
```bash
3943
npx adminforth create-app
4044
```
4145

42-
## Previews
46+
During the interactive initialization process, AdminForth will ask you to provide a local database URL.
4347

44-
<a href="https://adminforth.dev/docs/tutorial/Customization/customPages">Custom Dashboard</a>
45-
<br/>
46-
<img src="https://github.com/user-attachments/assets/aa899196-f7f3-4582-839c-2267f2e9e197" alt="AdminForth Dashboard demo" width="80%" />
48+
### Integrating AdminForth into your existing application
4749

48-
<a href="https://adminforth.dev/docs/tutorial/Plugins/chat-gpt">Text completion plugin (Copilot-style) using LLMs</a>
49-
<br/>
50+
If you want to build an admin panel for an existing project that already has a database with tables, you can provide the connection URL to your existing development database, such as a local or deployed one.
5051

51-
<img src="https://github.com/user-attachments/assets/cfa17cbd-3a53-4725-ab46-53c7c7666028" alt="AdminForth ChatGPT demo" width="80%" />
52+
After that, you may want to generate AdminForth resource files from your existing database tables:
5253

53-
<a href="https://adminforth.dev/docs/tutorial/Plugins/upload/#image-generation">Image Generation using image generation models</a>
54-
<br/>
55-
<img src="https://github.com/user-attachments/assets/b923e044-7e29-46ff-ab91-eeca5eee2b0a" alt="AdminForth DALE-E image generator demo" width="80%">
54+
```bash
55+
npx adminforth resource
56+
```
57+
58+
Resource files are needed for AdminForth to “know” about your tables and define how to work with them.
59+
60+
Use the command above every time you add new tables or change their schema.
61+
62+
### Starting from scratch
63+
64+
If you do not have a database yet, start an empty local database, for example PostgreSQL in Docker, and provide its URL to the AdminForth CLI.
65+
66+
If the adminforth CLI does not detect any tables, it will suggest adding Prisma as a migration tool. Prisma is not related to AdminForth, but it is one of the most convenient migration tools.
67+
68+
Please follow [getting started](https://adminforth.dev/docs/tutorial/gettingStarted/).
5669

70+
# For AdminForth developers
5771

58-
# For developers
72+
> Follow this section only if you want to make changes to the AdminForth framework or develop a plugin.
5973
60-
The most convenient way to add new features or fixes is using `dev-demo`. It imports the source code of the repository and plugins so you can edit them and see changes on the fly.
74+
The most convenient way to add new features or fixes is to use `dev-demo`. It imports the repository source code and plugins, so you can edit them and see changes on the fly.
6175

62-
# Requirements
76+
## Requirements
6377

6478
- **Node.js 20**
6579
- **Docker**

adminforth/basePlugin.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export default class AdminForthPlugin implements IAdminForthPlugin {
4747

4848
const seed = `af_pl_${this.constructor.name}_${resourceConfig.resourceId}_${uniqueness}`;
4949
this.pluginInstanceId = md5hash(seed);
50-
afLogger.trace(`🪲 AdminForthPlugin.modifyResourceConfig, ${seed}, 'id', ${this.pluginInstanceId}`);
50+
afLogger.trace({seed, pluginInstanceId: this.pluginInstanceId}, `🪲 AdminForthPlugin.modifyResourceConfig`);
5151
this.adminforth = adminforth;
5252
}
5353

0 commit comments

Comments
 (0)