softr-vibe-coding 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/datasources/writing.md +37 -0
- package/package.json +1 -1
- package/references/softr-mcp.md +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,10 @@ All notable changes to this skill are documented here. Versions follow [Semantic
|
|
|
4
4
|
|
|
5
5
|
Entries from 1.3.1 onward are generated automatically from git commit subjects between version bumps (see `.github/workflows/publish.yml`). Entries before 1.3.1 were backfilled by hand from the existing commit history.
|
|
6
6
|
|
|
7
|
+
## [2.1.2] - 2026-08-26
|
|
8
|
+
- Document four linked-record write traps verified live 2026-08-26
|
|
9
|
+
- Fail the build when main moves ahead of npm
|
|
10
|
+
|
|
7
11
|
## [2.1.1] - 2026-08-26
|
|
8
12
|
- Release 2.1.1
|
|
9
13
|
- Document external-URL attachment ingestion (copy, not link)
|
package/datasources/writing.md
CHANGED
|
@@ -291,6 +291,43 @@ parentAccount: "RECORD_ID_1"
|
|
|
291
291
|
string-array shape is the verified current form on Softr Database; if a linked-record write
|
|
292
292
|
fails on an Airtable-backed block, try the `[{ id }]` object shape before deeper debugging.
|
|
293
293
|
|
|
294
|
+
### Linked-record write traps (verified live 2026-08-26)
|
|
295
|
+
|
|
296
|
+
Four Softr Database behaviors proven by direct experiment on a live production build — a
|
|
297
|
+
49-link backfill across a self-referencing parent/child pair. They bite hardest in backfills
|
|
298
|
+
and schema work, and **none of them raises an error**.
|
|
299
|
+
|
|
300
|
+
1. **A single-valued link pair is enforced ON WRITE — and it clobbers silently.** With
|
|
301
|
+
`allowMultipleEntries: false` on the inverse side, writing child N's link to a parent
|
|
302
|
+
silently unlinks child N−1: no error, the earlier link just vanishes (16 of 49 backfill
|
|
303
|
+
links disappeared this way before it was caught). Pre-existing multi links DO survive a
|
|
304
|
+
flip from multi to single, which is why a scratch-table spike that flips an
|
|
305
|
+
already-linked pair reports the setting as "cosmetic only" and misleads — the
|
|
306
|
+
enforcement only fires on the next write. If one side must hold many links, both sides
|
|
307
|
+
must allow multiple entries; enforce any one-parent rule in the UI, not the schema.
|
|
308
|
+
|
|
309
|
+
2. **`allowMultipleEntries` is a TOP-LEVEL field property, not part of `options`.** The
|
|
310
|
+
workspace MCP's `update_field` silently ignores it when nested inside `options` — the
|
|
311
|
+
call succeeds and changes nothing. A Tables API `PUT /fields/{id}` with the property at
|
|
312
|
+
top level works.
|
|
313
|
+
|
|
314
|
+
3. **A Tables API field PUT that omits `options.inverseLinkFieldId` SEVERS the inverse
|
|
315
|
+
pairing** — it comes back `null` and the two sides stop mirroring each other. Always
|
|
316
|
+
echo `inverseLinkFieldId` inside the `options` you send, and re-read BOTH sides after
|
|
317
|
+
any linked-record field PUT to confirm the pairing survived.
|
|
318
|
+
|
|
319
|
+
4. **An empty multi-entry link reads back as `[]`, which is truthy in JS.** Any
|
|
320
|
+
"already linked — skip" guard written as `if (value)` matches every record after a
|
|
321
|
+
single→multi flip, so a resumable backfill re-processes nothing or skips everything.
|
|
322
|
+
Test presence explicitly:
|
|
323
|
+
|
|
324
|
+
```jsx
|
|
325
|
+
const hasLink = Array.isArray(v) ? v.length > 0 : !!v;
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
(The populated read shapes are in [fields.md](fields.md); this is the empty case, and
|
|
329
|
+
it becomes a write trap the moment a backfill uses it as a skip condition.)
|
|
330
|
+
|
|
294
331
|
## Writing to Field Types
|
|
295
332
|
|
|
296
333
|
Different Softr field types accept different value shapes in mutation payloads. The shape returned when you READ a field is often different from the shape you must SEND when you WRITE.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "softr-vibe-coding",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Claude Code skill for generating production-ready Softr Vibe Coding blocks (JSX). Installs into ~/.claude/skills/ and auto-updates on each Claude Code session.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"softr-vibe-coding": "./bin/cli.js"
|
package/references/softr-mcp.md
CHANGED
|
@@ -122,6 +122,13 @@ Known limits and behaviors (per official docs):
|
|
|
122
122
|
`{ filename, url }` on an ATTACHMENT field with any publicly reachable URL; Softr fetches it, stores its
|
|
123
123
|
own copy and generates thumbnails, so backfilling images from another system is one write per record
|
|
124
124
|
with no upload step. Verified 2026-08-26 — see [../datasources/writing.md](../datasources/writing.md#attachment).
|
|
125
|
+
- **`update_field` silently ignores `allowMultipleEntries` nested inside `options`** — it is a TOP-LEVEL
|
|
126
|
+
field property; the call succeeds and changes nothing (verified 2026-08-26). To flip a LINKED_RECORD
|
|
127
|
+
field between single and multi, `PUT` it via the Tables API with `allowMultipleEntries` at top level —
|
|
128
|
+
and always echo `options.inverseLinkFieldId` in that PUT, because omitting it severs the inverse
|
|
129
|
+
pairing. Full write-up, including the silent on-write clobbering of single-valued link pairs and the
|
|
130
|
+
truthy-`[]` empty-link read shape:
|
|
131
|
+
[../datasources/writing.md](../datasources/writing.md#linked-record-write-traps-verified-live-2026-08-26).
|
|
125
132
|
- Limits: 100 records per `create_records` call, 200 records per read (silently capped, not an error), 2 group-by fields in `aggregate_data`. For big tables prefer a filter or aggregate over paging.
|
|
126
133
|
|
|
127
134
|
Typical Vibe Coding uses: "list every field on `Wigs` with id, name, type, and dropdown options", "what's the option id for `Payment status` = 'Partially paid'?", "show 3 sample records so we know value shapes", "verify the field id in my `q.select()` exists". This eliminates the field-id-typo / wrong-option-uuid class of bugs entirely.
|