Commit c0517ee

Eric Bower  ·  2026-03-28 23:12:36 -0400 EDT
parent c0208b3
docs: rm auto form
5 files changed,  +6, -135
+0, -124
......@@ -1,124 +0,0 @@
1-# Auto-Form Feature for pgs.sh
2-
3-## Overview
4-
5-The auto-form feature allows users to create HTML forms on their pgs.sh sites that automatically submit data to the pgs database. Form submissions can then be retrieved via the pgs CLI in JSON format.
6-
7-## How It Works
8-
9-1. Form submissions are automatically captured and stored in PostgreSQL
10-2. Users can retrieve form data via the pgs CLI
11-
12-## Database Schema
13-
14-```sql
15-CREATE TABLE form_entries (
16- id uuid NOT NULL DEFAULT uuid_generate_v4(),
17- user_id uuid NOT NULL,
18- name VARCHAR(255) NOT NULL,
19- data jsonb NOT NULL,
20- created_at timestamp without time zone NOT NULL DEFAULT NOW(),
21- CONSTRAINT form_entries_pkey PRIMARY KEY (id),
22- CONSTRAINT fk_form_entries_users
23- FOREIGN KEY(user_id)
24- REFERENCES app_users(id)
25- ON DELETE CASCADE
26-);
27-
28-CREATE INDEX IF NOT EXISTS idx_form_entries_user ON form_entries(user_id);
29-CREATE INDEX IF NOT EXISTS idx_form_entries_name ON form_entries(name);
30-```
31-
32-### Migration
33-
34-Run the migration:
35-```bash
36-make latest
37-```
38-
39-Or run all migrations:
40-```bash
41-make migrate
42-```
43-
44-## HTML Form Example
45-
46-```html
47-<form method="POST" action="/forms/example" data-pgs="true">
48- <p>
49- <label>Your Name: <input type="text" name="name" /></label>
50- </p>
51- <p>
52- <label>Your Email: <input type="email" name="email" /></label>
53- </p>
54- <p>
55- <label>Your Role: <select name="role[]" multiple>
56- <option value="leader">Leader</option>
57- <option value="follower">Follower</option>
58- </select></label>
59- </p>
60- <p>
61- <label>Message: <textarea name="message"></textarea></label>
62- </p>
63- <p>
64- <button type="submit">Send</button>
65- </p>
66-</form>
67-```
68-
69-## CLI Commands
70-
71-### List all form names for a user
72-```bash
73-ssh pgs.sh forms ls
74-```
75-
76-### Get form submissions for a specific form
77-```bash
78-ssh pgs.sh forms show example
79-```
80-
81-Output (JSON):
82-```json
83-[
84- {
85- "id": "uuid",
86- "name": "contact",
87- "data": {
88- "name": "John Doe",
89- "email": "john@example.com",
90- "role": ["leader", "follower"],
91- "message": "Hello!"
92- },
93- "created_at": "2026-03-05T12:00:00Z"
94- }
95-]
96-```
97-
98-### Delete all submissions for a form
99-```bash
100-ssh pgs.sh forms rm example --write
101-```
102-
103-## Data Storage
104-
105-- Form data is stored in PostgreSQL `form_entries` table
106-- Each submission is a JSON object with form field names as keys
107-- Data is associated with the user, not the project
108-- Form data is deleted when the user account is deleted (CASCADE)
109-
110-## Implementation Details
111-
112-### Database Methods
113-
114-```go
115-InsertFormEntry(userID, name string, data map[string]interface{}) error
116-FindFormEntriesByUserAndName(userID, name string) ([]*db.FormEntry, error)
117-FindFormNamesByUser(userID string) ([]string, error)
118-RemoveFormEntriesByUserAndName(userID, name string) error
119-```
120-
121-## More features
122-
123-- Form validation and confirmation pages
124-- CSRF token in form and validated in post handler
+1, -3
......@@ -144,9 +144,7 @@ func (h *UploadAssetHandler) Read(s *pssh.SSHServerConnSession, entry *sendutils
144144 fileInfo.FSize = info.Size
145145 fileInfo.FModTime = info.LastModified
146146
147- reader := storage.NewAllReaderAt(contents)
148-
149- return fileInfo, reader, nil
147+ return fileInfo, contents, nil
150148 }
151149
152150 func (h *UploadAssetHandler) List(s *pssh.SSHServerConnSession, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {
+1, -2
......@@ -123,7 +123,6 @@ func (h *UploadImgHandler) Read(s *pssh.SSHServerConnSession, entry *sendutils.F
123123 if err != nil {
124124 return nil, nil, err
125125 }
126- reader := storage.NewAllReaderAt(contents)
127126
128127 fileInfo := &sendutils.VirtualFile{
129128 FName: cleanFilename,
......@@ -132,7 +131,7 @@ func (h *UploadImgHandler) Read(s *pssh.SSHServerConnSession, entry *sendutils.F
132131 FModTime: info.LastModified,
133132 }
134133
135- return fileInfo, reader, nil
134+ return fileInfo, contents, nil
136135 }
137136
138137 func (h *UploadImgHandler) Write(s *pssh.SSHServerConnSession, entry *sendutils.FileEntry) (string, error) {
+3, -3
......@@ -10,9 +10,8 @@ type ReadAndReaderAt interface {
1010 }
1111
1212 type ReadAndReaderAtCloser interface {
13- io.Reader
1413 io.ReaderAt
15- io.ReadCloser
14+ io.ReadSeekCloser
1615 }
1716
1817 func NopReadAndReaderAtCloser(r ReadAndReaderAt) ReadAndReaderAtCloser {
......@@ -23,4 +22,5 @@ type nopReadAndReaderAt struct {
2322 ReadAndReaderAt
2423 }
2524
26-func (nopReadAndReaderAt) Close() error { return nil }
25+func (nopReadAndReaderAt) Close() error { return nil }
26+func (nopReadAndReaderAt) Seek(int64, int) (int64, error) { return 0, nil }
+1, -3
......@@ -109,9 +109,7 @@ func (h *UploadAssetHandler) Read(s *pssh.SSHServerConnSession, entry *utils.Fil
109109 fileInfo.FSize = info.Size
110110 fileInfo.FModTime = info.LastModified
111111
112- reader := NewAllReaderAt(contents)
113-
114- return fileInfo, reader, nil
112+ return fileInfo, contents, nil
115113 }
116114
117115 func (h *UploadAssetHandler) List(s *pssh.SSHServerConnSession, fpath string, isDir bool, recursive bool) ([]os.FileInfo, error) {