HarperFast / HarperFast/studio

Browse: elements-less array column named like a table is mis-rendered as a relationship

Open Beginner friendly
#1,487 0 comments 0 reactions 0 assignees View on GitHub
admin & data
Dominant language
TypeScript
Stars
5
Forks
4
Avg merge
1d 8h
Merged PRs (30d)
40

Description

## Summary

In the database browse view, a **plain array column** can be mis-rendered as a to-many relationship (a `Table →` reverse-link chip) when it has no element type in `describe_table` **and** happens to be named like a sibling table. Flagged by @DavidCockerill in review of #1438 as low-priority / non-blocking.

## Where

`src/features/instance/databases/functions/relationshipAttributes.ts` → `relatedTableNameOf()` → `findSiblingTableByName()`. For an attribute reported by `describe_table` as `{ type: 'array' }` with **no `elements`**, we match its name (and simple singular/plural variants) against sibling table names and treat it as a to-many relationship. Regression coverage that pins the current behavior: the "legacy elements-less relationships and reverse foreign keys" block in `relationshipAttributes.test.ts`.

Only **elements-less** arrays are affected. Typed scalar arrays (`elements: 'String'`) and typed to-many relationships (`elements: ''`) are unambiguous and unaffected.

## Why it's a false positive (analysis)

Walking the two server regimes, an elements-less array in `describe_table` is **never** a Harper-modeled relationship:

- **Harper 5.1+**: relationship attributes are omitted from `describe_table` entirely (see #1438 / the describe regression). So anything that *does* appear as `{ type: 'array' }` is a persisted plain/legacy array column, not a relationship → name match = false positive.
- **Harper 4.x**: to-many relationships appear in describe with `elements` **typed** (e.g. `reviews: [Review]` → `{ type: 'array', elements: 'Review' }`, verified against 4.7.28). A real to-many is therefore caught by the typed path, not the elements-less name heuristic.

So the elements-less name heuristic has no regime where it catches a relationship Harper actually models — it only ever fires on plain array data. The `data.Albums.tracks` case that motivated it "worked" by luck: `Tracks.albumId` lined up by convention, but `tracks` was not a declared `@relationship`.

Real relationships are already covered without the heuristic: schema-declared ones via `schemaRelationships.ts` (exact `from:`/`to:`, the only source on 5.1) and typed to-many via describe on 4.x.

## Options

1. **Remove the elements-less name heuristic** (`findSiblingTableByName`) — rely solely on schema-declared relationships + elements-typed describe. Removes the false positive at the root. Only behavior change: an un-declared elements-less array named like a table renders as plain JSON instead of a guessed reverse-link. Schema-declared to-many (e.g. `Category.products`) is unaffected (detected via schema, not this heuristic). **Recommended.**
2. **Gate on schema presence** — apply the heuristic only to tables absent from all parsed component schemas. More conservative but keeps a guess for truly schema-less data.
3. **Corroborate** — only treat an elements-less array as a relationship if the sibling table has a plausible reverse foreign key back-referencing this table. Narrows but doesn't eliminate false positives; couples detection to reverse-key inference.

Recommendation: option 1. If we want to keep a best-effort link for schema-less legacy data, option 2.

## Not urgent

The column def, header, and data are all still present either way; the only impact is a plain array being shown as a link chip instead of JSON. No data correctness or write-path impact.

Contributor guide

Open the contributing guide

Research direction

Start in src/features/instance/databases/functions/relationshipAttributes.ts at relatedTableNameOf() and findSiblingTableByName(), then inspect the legacy elements-less relationships and reverse foreign keys block in relationshipAttributes.test.ts. Ensure elements-less plain arrays render as data while schema-declared and elements-typed relationships remain supported, and update the regression coverage to verify the distinction.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
databases, frontend
Issue type
Bug
Difficulty
2/5
Estimated time
Half a day
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
84/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.