データモデル Data model

モバイルアプリは管理者ポータル・オーナーポータルと同じ Supabase PostgreSQL データベースを共有します。 そのため、データモデルは 管理者ポータルのデータモデル と完全に同一です。 本ページでは、モバイルアプリから直接読み書きする主要エンティティを中心に整理します。

The mobile app shares the same Supabase PostgreSQL database as the admin and owner portals, so the data model is identical to the admin portal data model. This page focuses on the core entities the mobile app reads from and writes to directly.

一次情報源:Source of truth: スキーマの正本は parky/infra/supabase/migrations/000_init_schema.sql。 コードマスター(ステータス・種別等の列挙値)は codes テーブルで管理され、 CLAUDE.md のコードマスター方針に従い、列挙値は英語小文字のコード値で保持します。 The canonical schema lives in parky/infra/supabase/migrations/000_init_schema.sql. Enumerated values (status, kind, etc.) are managed in the codes master table, and per the CLAUDE.md code-master policy they are stored as lowercase English code values.

7.1 ドメイン俯瞰図 7.1 Domain map

flowchart LR
  subgraph Parking["🅿️ 駐車場ドメイン"]
    PL[parking_lots]
    PLI[parking_lot_images]
    PLT[parking_lot_tags]
    PLPR[parking_lot_pricing_rules]
    PLH[parking_lot_hours]
    PLDO[parking_lot_date_overrides]
    %% parking_lot_attributes (028) と parking_lot_payment_methods (057) は tags に統合済み
    PR[parking_reviews]
    PS[parking_sessions]
  end
  subgraph Users["👤 ユーザー"]
    AU[app_users]
    USP[user_saved_parkings]
    UAL[user_activity_logs]
    US[user_subscriptions]
    UPT[user_push_tokens]
    UN[user_notifications]
    UE[user_exp]
    UB[user_badges]
    UBP[user_badge_progress]
    UT[user_themes]
    UAT[user_active_themes]
  end
  subgraph Game["🏆 ゲーミフィケーション"]
    BD[badge_definitions]
    LD[level_definitions]
    AER[activity_exp_rules]
  end
  subgraph Content["📝 コンテンツ"]
    ART[articles]
    ADS[ads]
    TAG[tags]
    HB[home_banners]
    ER[error_reports]
    ST[support_tickets]
  end
  subgraph Search["🔎 検索関連"]
    UD[user_destinations]
  end
  subgraph Sys["⚙️ マスター"]
    CD[codes]
    SP[subscription_plans]
  end

  PL --> PLI
  PL --> PLT
  PL --> PLPR
  PL --> PLH
  PL --> PLDO
  PL --> PR
  PL --> PS
  AU --> PS
  AU --> PR
  AU --> USP
  AU --> UAL
  AU --> US
  AU --> UPT
  AU --> UN
  AU --> UE
  AU --> UB
  AU --> UBP
  AU --> UT
  AU --> UAT
  AU --> UD
  BD --> UBP
  BD --> UB
  LD --> UE
  US --> SP

7.2 主要テーブル定義(モバイル視点) 7.2 Core table definitions (mobile-centric view)

parking_lots core

駐車場の中核テーブル。座標の SoT は PostGIS の location (geography 4326)。lat/lng は表示用にトリガーで派生。shape_type で point/line/area を切替、code (citext) は自然キー。周辺検索は nearby_parking_lots() RPC を使用。

The core lot table. location is the coordinate SoT; lat/lng are trigger-derived. shape_type selects point/line/area, code (citext) is the natural key. Nearby search uses the nearby_parking_lots() RPC.

カラムColumn Type 備考Notes
iduuidPK
codecitext NOT NULL自然キー (URL / 連携ID)Natural key (URL / integration ID)
nametext NOT NULL
addresstext表示用住所Display address
locationgeography(Point, 4326)座標 SoT (PostGIS)Coordinate SoT (PostGIS)
lat / lngdouble precision表示用。実体は locationDisplay-only; source is location
areageometryshape_type='area' 用ポリゴンPolygon for shape_type='area'
shape_typetext NOT NULL (default 'point')point / line / area
parent_iduuid親駐車場 (バリアント分割用)Parent lot (for variants)
variant_labeltextバリアント識別ラベルVariant label
total_spacesint収容台数Capacity
operating_hourstext表示用文字列。詳細は parking_lot_hoursDisplay string; detail in parking_lot_hours
structuretextflat / multistory / underground 等flat / multistory / underground, etc.
entry_methodtextgate / flap / barrier_free 等gate / flap / barrier_free, etc.
entry_difficultytext入庫難易度のコードEntry-difficulty code
max_height_m / max_width_m / max_length_m / max_weight_tnumeric車両制限Vehicle limits
min_clearance_cmint最低地上高Minimum clearance
max_tire_width_mmintタイヤ幅制限Tire-width limit
max_parking_duration_minint連続駐車可能時間 (分)Max continuous parking (minutes)
receipt_availableboolean領収書発行可否Receipt available
operator_codetext運営会社コード (codes.operator)Operator code (codes.operator)
place_idtextGoogle Places IDGoogle Places ID
statustext NOT NULL (default 'active')codes.parking_lot_status: pending / active / on_hold / withdrawn
sourcetext (default 'manual')データ取得元Data origin
raw_texttext取込元の生データ (デバッグ用)Raw ingest text (debug)
created_at / updated_attimestamptz
deleted_attimestamptzソフトデリートSoft delete

parking_lot_pricing_groups core 2026-04-24 new

駐車場内の料金ポリシー集約単位。複数の parking_spots が同一 group を参照することで料金の共有編集が可能。(parking_lot_id, code) で一意。

Pricing-policy aggregation unit inside a lot. Multiple spots can share a group so pricing can be edited in bulk. Unique on (parking_lot_id, code).

カラム備考
iduuidPK
parking_lot_iduuid NOT NULLFK → parking_lots
codecitext NOT NULL自然キー (lot 内一意)Natural key, unique within a lot
nametext NOT NULL表示名 (例: 普通車スタンダード)Display name (e.g. "Standard – sedan")
is_defaultboolean (default false)既定 groupDefault group
display_orderint (default 0)
created_at / updated_attimestamptz

parking_spots core 2026-04-24 new

駐車場内の個別車室。parking_sessions.parking_spot_idNOT NULL なので、セッション作成時には spot を必ず確定させる必要がある。(parking_lot_id, code) で partial UNIQUE (soft delete 考慮)。

Individual parking spot. parking_sessions.parking_spot_id is NOT NULL, so a session always pins to a specific spot. Partial UNIQUE on (parking_lot_id, code) respecting soft delete.

カラム備考
iduuidPK
parking_lot_iduuid NOT NULLFK → parking_lots
pricing_group_iduuid NOT NULLFK → parking_lot_pricing_groups
codecitext NOT NULL自然キー (例: A-12)Natural key (e.g. A-12)
vehicle_type_maxtext最大対応車種Max vehicle type accepted
is_ev_chargerbooleanEV 充電器ありHas EV charger
ev_connector_typetextCHAdeMO / CCS / Tesla 等CHAdeMO / CCS / Tesla, etc.
accessibilitytextバリアフリー区分Accessibility class
width_mm / length_mm / height_mmint区画寸法Spot dimensions
floorplan_x / floorplan_ynumeric場内マップ用座標Floor-plan XY
locationgeography(Point)spot 単位の座標Spot-level GPS
is_reservableboolean
is_activeboolean (default true)
metajsonb (default {})
created_at / updated_at / deleted_attimestamptz

parking_lot_hours core 2026-04-24 updated

駐車場の時間窓。2026-04-24 に window_type カラムを追加、1 行 = 1 種別の時間窓として正規化しました。 モバイルアプリは詳細画面で「営業中」「今すぐ入庫可」「今すぐ出庫可」バッジを表示する際に、Mobile BFF 経由で派生値 (derived.is_open_now / can_enter_now / can_exit_now) を受け取ります。

Time-window rows for a parking lot. 2026-04-24 added window_type. The mobile app receives derived flags (derived.is_open_now / can_enter_now / can_exit_now) from the Mobile BFF rather than evaluating rules client-side.

カラムColumn Type 備考Notes
window_typecode (text)business / entry / exit / after_hours_exitcodes.parking_hours_window_type
day_typecode (text)weekday / saturday / sunday / holiday / holiday_eve / all
day_of_weeksmallint0=Sun〜6=Sat
is_24h / is_closedboolean
open_time / close_timetext NOT NULLHH:MM 文字列。24:00 表記許容のため text 型HH:MM as text (allows 24:00)
effective_from / effective_todate期間限定ルール

parking_lot_date_overrides core 2026-04-24 new

特定日のオーバーライド (花火大会・元旦特別営業など)。Mobile BFF は駐車場詳細 API のレスポンスに date_overrides[] を含め、当日の active_overridederived に載せます。 アプリ側では「今日は花火大会のため 12:00 以降のみ入庫可」等のバナー表示に利用。

Per-day override rows. The Mobile BFF returns date_overrides[] and sets derived.active_override for the current day so the app can show banners like "fireworks night — entry after 12:00".

カラム備考
parking_lot_id + override_dateuuid + dateUNIQUE
labeltext例: 隅田川花火大会
hoursjsonbキー: business / entry / exit / after_hours_exit
pricingjsonb (array)NULL=通常 / []=無料 / 配列=置換

判定の優先順: 日付オーバーライド → 祝日行 (jp_holidays 参照) → 曜日行 → day_type → all。 詳細は 2026-04-24 ADR

parking_lot_pricing_rules core

料金エンジンのルール。pricing_group_id を必ず持ち、rule_order で優先順、category / day_type / time_start / time_end で条件絞り込み、cap_* で上限を表現する。金額は minor unit の bigint (JPY は 1 倍)。

Fee-engine rules. Each row belongs to a pricing_group_id and is ordered by rule_order; matching uses category / day_type / time_start / time_end; caps via the cap_* family. Money is bigint in minor units (×1 for JPY).

カラムColumn Type 備考Notes
iduuidPK
parking_lot_iduuid NOT NULLFK → parking_lots
pricing_group_iduuid NOT NULLFK → parking_lot_pricing_groups (2026-04-24 階層化で必須化)(required by the 2026-04-24 hierarchy migration)
rule_orderint NOT NULL (default 0)小さい順に評価Lower numbers evaluated first
categorytext NOT NULL時間制 / 最大料金 / 一回 / フラット 等e.g. hourly / max-fee / once / flat
day_typetext NOT NULL (default 'all')codes.day_type: weekday / saturday / sunday / holiday / holiday_eve / all
time_start / time_endtext時間帯 (HH:MM 文字列。24:00 表記可)Time window as HH:MM text (allows 24:00)
per_minutesint課金単位 (分)Billing unit in minutes
price_minorbigint単位あたり minor 通貨 (JPY なら円)Price per unit, minor currency
cap_typetextonce / per_24h / per_window
cap_duration_hoursint最大料金の対象時間 (時間単位)Cap window in hours
cap_price_minorbigint最大料金 (minor 通貨)Cap amount, minor currency
cap_repeatboolean (default true)cap を繰り返し適用するかReapply cap each window
cap_scopetext日跨ぎ / 入庫起点 等のスコープCap scope (e.g. calendar day / entry-relative)
created_attimestamptz

parking_sessions core

モバイルアプリの中心エンティティ。parking_spot_idNOT NULL で、セッションは必ず特定の spot に紐付く。金額は total_amount_minor (bigint, minor unit)。geo_verified / geo_distance_m で開始時の位置検証、client_request_id で冪等性、fee_mismatch_flag / user_entered_fee_minor でユーザー手入力金額との突合を行う。updated_at / deleted_at は無く、ソフトデリートではなく status='cancelled' + cancelled_reason で運用

The mobile app's central entity. parking_spot_id is NOT NULL — every session pins to a specific spot. Amount is bigint in minor units. geo_verified / geo_distance_m validate start location, client_request_id enforces idempotency, fee_mismatch_flag reconciles user-entered fees. No updated_at / deleted_at; cancellation is via status='cancelled' + cancelled_reason.

カラムColumn Type 備考Notes
iduuidPK
user_iduuid NOT NULLFK → app_users
parking_lot_iduuid NOT NULLFK → parking_lots
parking_spot_iduuid NOT NULLFK → parking_spots (2026-04-24 階層化で必須化)(required by the 2026-04-24 hierarchy migration)
started_attimestamptz NOT NULL入庫時刻Entry time
ended_attimestamptz出庫時刻 (NULL=駐車中)Exit time (NULL = still parked)
planned_end_attimestamptz予定終了時刻 (session_notificationsplanned_end_minus が参照)Planned end (driver of planned_end_minus session notifications)
statustext NOT NULL (default 'parking')codes.session_status: parking / completed / cancelled
cancelled_reasontextcancel 時の理由 codesCancellation reason code
vehicle_typetextcodes.vehicle_type: sedan / kei / large / bike / minivan / high_roof
total_amount_minorbigint最終確定額 (minor 通貨。JPY は円)Final billed amount in minor units (yen for JPY)
user_entered_fee_minorintユーザーが手入力した金額 (突合用)User-entered fee, used to flag mismatch
fee_mismatch_flagboolean (default false)計算額と手入力額の乖離検知True when calculated vs entered diverge
memotextメモFree-form memo
bad_reasontext不正/不審セッションの分類Bad-session classification
start_lat / start_lngdouble precision入庫時 GPSEntry-time GPS snapshot
end_lat / end_lngdouble precision出庫時 GPSExit-time GPS snapshot
geo_verifiedboolean位置検証成功 (gamification cap で参照)Geo verification result (gamification gate)
geo_distance_mnumeric入庫地点と lot 位置の距離 (m)Distance from start GPS to lot location (m)
client_request_iduuid冪等性キーIdempotency key
created_attimestamptz

個人評価 (good / bad) は別テーブル parking_lot_ratings でユーザー × 駐車場の M:N として保持する (セッションのカラムでは無い)。レビュー本文は parking_reviews

Personal ratings (good / bad) live in parking_lot_ratings (user × lot M:N), not as a session column. Full reviews live in parking_reviews.

parking_reviews

駐車場レビュー (UGC)。status='approved' のみ公開表示・集計対象 (parking_lot_avg_rating view が参照)。オーナー返信は owner_reply 系列で保持。画像はこのテーブルに保存せず、別途 assets + parking_session_photos を経由する。

User reviews (UGC). Only status='approved' is publicly visible and counted (parking_lot_avg_rating view). Owner replies live in the owner_reply* columns. Images are not stored on this table — use assets + parking_session_photos.

カラムColumn Type 備考Notes
iduuidPK
parking_lot_iduuid NOT NULLFK → parking_lots
user_iduuid投稿ユーザー (退会で NULL 可)Posting user (nullable to allow withdrawn users)
user_nametext NOT NULL投稿時の表示名スナップショット (退会後も表示)Display-name snapshot at post time
ratingint NOT NULL1–5
commenttext
statustext NOT NULL (default 'pending')codes.review_status: pending / approved / rejected / hidden
admin_notetext運営側の社内メモInternal admin note
reviewed_by / reviewed_atuuid / timestamptz審査担当 admin と審査時刻Reviewer admin + reviewed time
is_flaggedboolean (default false)通報フラグFlagged for review
flag_reasontext
owner_replytextオーナー返信本文Owner reply body
owner_replied_at / owner_replied_bytimestamptz / uuid
exp_awarded_attimestamptzEXP 付与済みかの記録 (二重付与防止)When XP was granted (prevents double-grant)
created_at / updated_at / deleted_attimestamptz

app_users core

エンドユーザー。auth_user_idauth.users と 1:1 紐付け、RLS は auth_user_id = auth.uid() で自己行のみ。退会は status='withdrawn' + PII 匿名化で運用 (deleted_at 列は無い)。アバター / 通知設定 / locale は別テーブルで管理する (下表参照)。

End users. Linked 1:1 to auth.users via auth_user_id; RLS limits access to auth_user_id = auth.uid(). Withdrawals are status='withdrawn' + PII anonymization (no deleted_at). Avatar / notification prefs / locale live in separate tables.

カラムColumn Type 備考Notes
iduuidPK
auth_user_iduuidFK → auth.users (RLS の主軸)
display_nametext NOT NULL
handletext@ハンドル (UNIQUE)Public handle (UNIQUE)
emailtext NOT NULL
vehicle_typetext (default 'sedan')codes.vehicle_type: sedan / kei / large / bike / minivan / high_roof
premiumboolean (default false)プレミアム契約中フラグPremium subscription flag
statustext NOT NULL (default 'active')codes.user_status: active / withdrawn / suspended / blocked
profile_visibilitytext NOT NULL (default 'friends')public / friends / private
device_fingerprintstext[]既知デバイス指紋 (referral 不正検知)Known device fingerprints (referral abuse detection)
signup_ipinet登録時 IPSignup IP
referral_code_usedtext登録時に使った招待コードReferral code used at signup
last_active_attimestamptz
created_attimestamptz

付随テーブル: user_notification_prefs (通知種別ごとの push / in_app / email ON-OFF)、user_consents (同意履歴)、user_device_permissions (OS パーミッション現在値)、user_vehicles (登録車両 N 件)、user_search_presets / user_search_preferencesuser_referral_codesuser_destinationsuser_streaks。 アバター画像は assets テーブルに entity_type='app_user' + entity_id=app_users.id で関連付ける。

Companion tables: user_notification_prefs (per-type push / in_app / email toggles), user_consents, user_device_permissions, user_vehicles, user_search_presets / user_search_preferences, user_referral_codes, user_destinations, user_streaks. Avatar images are stored in assets with entity_type='app_user' + entity_id=app_users.id.

user_notification_prefs notifications

通知種別ごとに push / in_app / email の ON-OFF を保持する。app_users.notification_prefs jsonb 列は存在しない

Per-notification-type push / in_app / email toggles. There is no app_users.notification_prefs jsonb column.

カラム備考
iduuidPK
user_iduuid NOT NULLFK → app_users
notif_typetext NOT NULLcodes.notif_type: system / info / promo / review_reminder, ...
push_enabledboolean (default true)
in_app_enabledboolean (default true)
email_enabledboolean (default false)
updated_attimestamptz

user_push_tokens

FCM デバイストークン。起動時に upsert し、Push 送信時に参照します。

FCM device tokens. Upserted on app boot and read when sending push notifications.

カラムColumn Type 備考Notes
iduuidPK
user_iduuidFK
device_idtextデバイス一意IDUnique device ID
fcm_tokentextFCM v1 トークンFCM v1 token
device_typecode (text)ios / android(device_type マスター)ios / android (via the device_type master)
app_versiontext
last_seen_attimestamptz
UNIQUE (user_id, device_id)

user_notifications

アプリ内通知の受信箱。Push と同じレコードを ここに INSERT し、Realtime で端末に配信されます。

The in-app notification inbox. The same record that backs a push is INSERTed here and streamed to devices via Realtime.

カラムColumn Type 備考Notes
iduuidPK
user_iduuidFK
notif_typecode (text)system/promo/fee_alert/session/review, etc.
notif_categorycode (text)カテゴリグループ(UIタブ分類)Category group (UI tab bucket)
titletext
bodytext
deep_linktextタップで遷移する画面(parky://Target screen opened on tap (parky://)
payloadjsonb任意の付帯情報Arbitrary attached data
sent_attimestamptz送信時刻Sent-at time
read_attimestamptz既読時刻(NULL=未読)Read-at time (NULL = unread)
delivered_attimestamptz端末到達Delivered to device
statuscode (text)notif_status: queued/sent/delivered/failed

user_saved_parkings

カラムColumn Type
user_id, parking_lot_iduuid (PK 複合)uuid (composite PK)
created_attimestamptz

user_activity_logs

全ての行動イベント。metadata(JSONB)にイベント固有の詳細を保持し、バッジ条件エンジンはこのメタデータをドット記法パスで評価します。

Every activity event. Event-specific detail lives in metadata (JSONB), and the badge condition engine evaluates that metadata via dot-notation paths.

カラムColumn Type 備考Notes
iduuidPK
user_iduuidFK
activity_typetextsession_start / session_end / review_post / search, etc.
metadatajsonbイベント詳細Event detail
occurred_attimestamptz

user_exp / level_definitions / activity_exp_rules / badge_definitions / user_badges / user_badge_progress gamification

管理者ポータルと同じゲーミフィケーション基盤を共有。モバイルは書き込みしません(DB トリガ・Cloudflare Workers 経由で自動更新)。

Shares the same gamification stack as the admin portal. The mobile app never writes to it directly — updates are driven by DB triggers and Cloudflare Workers.

user_subscriptions / subscription_plans revenue

articles / ads

メディア記事と広告のマスター。モバイルは read-only。

Master tables for media articles and ads. The mobile app is read-only.

home_banners 2026-04-24 new

ホーム画面上部に表示される誘導・広告バナー。GET /v1/mobile/views/home-feedbanners[] として配信される。 area_places / sponsors は座標付きの地理的スポット用の VIEW であり、バナー(広告・誘導カード)とは別概念。

Horizontal banner slots rendered at the top of the home screen. Delivered via GET /v1/mobile/views/home-feed as banners[]. Distinct from area_places / sponsors, which are geographic points on the map.

カラムColumn Type 備考Notes
iduuidPK
slot_keytexthome_top / home_middle / home_bottom
title / subtitletext
image_asset_iduuidFK → assets。R2 上の画像FK → assets. Image on R2
image_urltext外部画像 URL(asset と排他想定)External image URL (mutually exclusive with asset)
link_typetextexternal / deep / none
link_urltextexternal は https URL、deepparky://…external: https URL; deep: parky://…
display_orderint同一 slot 内の表示順Order within a slot
is_activeboolean
starts_at / ends_attimestamptz配信期間。RLS で範囲外を非表示Delivery window; RLS hides rows outside this range

user_destinations 2026-04-24 new

Wherto 目的地入力欄のオートコンプリート履歴。GET /v1/mobile/views/destinations で最近候補を上位表示するためのユーザー個別テーブル。 Mapbox Search Box API(契約済の場合)から取得した place_id を持てば次回以降の重複判定に利用される。

User-scoped autocomplete history for the Wherto destination input. GET /v1/mobile/views/destinations surfaces recent picks first. When a Mapbox Search Box place_id is attached, it deduplicates subsequent selections.

カラムColumn Type 備考Notes
iduuidPK
user_iduuidFK → app_users
nametext目的地の表示名(駅名・施設名等)Display name (station, POI)
addresstext
lat / lngdouble precision
place_idtextMapbox 等の外部 place ID。(user_id, place_id) で UNIQUEExternal place ID (e.g. Mapbox). UNIQUE by (user_id, place_id)
use_countint選択回数。重複選択で +1Selection count; incremented on collision
last_used_attimestamptz

support_tickets / error_reports ops

codes master

カテゴリ付きラベル辞書。起動時に一括フェッチし、クライアントのドロップダウン・ラベル表示に使用。実 DB 検証済の主要カテゴリ:

A category-keyed label dictionary. Fetched once on app boot to power every dropdown / label. Verified categories from the live DB:

category_idcodes
user_statusactive / withdrawn / suspended / blocked
vehicle_typesedan / kei / large / bike / minivan / high_roof
session_statusparking / completed / cancelled
review_statuspending / approved / rejected / hidden
parking_lot_statuspending / active / on_hold / withdrawn
parking_hours_window_typebusiness / entry / exit / after_hours_exit
day_typeweekday / saturday / sunday / holiday / holiday_eve / all
tag_categoryfacility / marketing / payment / other
notif_typesystem / info / promo / review_reminder / ...
notif_statusdraft / scheduled / sending / sent / failed

7.3 モバイル固有の読み書きマトリクス 7.3 Mobile read/write matrix

テーブルTable モバイル読取Mobile read モバイル書込Mobile write RLS 要点RLS key points
parking_lots / parking_lot_pricing_groups / parking_spots (+ hours / pricing_rules / images / tags)(+ hours / pricing_rules / images / tags)✅ 全件✅ Allstatus='active' かつ deleted_at IS NULLstatus='active' and deleted_at IS NULL
parking_sessions✅ 自分のみ✅ Self only✅ 自分のみ✅ Self onlyuser_id = auth.uid()
parking_reviews✅ approved + 自分の draft✅ approved + own drafts✅ 自分のレビュー✅ Own reviews同上Same as above
app_users✅ 自分のみ✅ Self only✅ 自分のプロフィール✅ Own profile同上Same as above
user_saved_parkings✅ 自分のみ✅ Self only✅ 自分のみ✅ Self only同上Same as above
user_notifications✅ 自分のみ✅ Self onlyread_at 更新のみread_at updates only同上Same as above
user_push_tokens✅ 自分のみ✅ Self only✅ 自分のみ (upsert)✅ Self only (upsert)同上Same as above
user_activity_logs✅ INSERT のみ✅ INSERT only自分ユーザーIDのみ許可Only the caller's user ID is allowed
user_exp/user_badges/user_badge_progress✅ 自分のみ✅ Self only❌(DBトリガで自動)❌ (auto via DB triggers)同上Same as above
user_subscriptions✅ 自分のみ✅ Self only❌(Edge 経由)❌ (via Cloudflare Workers)同上Same as above
support_tickets✅ 自分のみ✅ Self only✅ INSERT + 返信✅ INSERT + replies同上Same as above
error_reports✅ 自分のみ✅ Self only✅ INSERT のみ✅ INSERT only同上Same as above
articles / ads✅ 公開中✅ Publishedpublished_at <= now()
codes✅ 全件✅ All

7.4 データライフサイクル 7.4 Data lifecycle

データData 作成Creation 更新Update 削除Deletion
ユーザーUser サインアップ時On signup プロフィール編集Profile edits 退会 → withdrawn + 個人情報匿名化Withdrawal → withdrawn + PII anonymized
駐車セッションParking session 駐車開始時On parking start 駐車中・駐車終了時During and at end of parking status='cancelled' + cancelled_reason でキャンセル管理 (deleted_at は無し)Cancelled via status='cancelled' + cancelled_reason (no deleted_at)
レビューReview 投稿時On post 編集(一定期間内)Edit (within a grace window) ソフト削除Soft delete
通知Notification 送信時On send 既読化Mark as read 90日経過で自動アーカイブ(Cron)Auto-archived after 90 days (cron)
活動ログActivity log 行動時On activity 2年経過で集計化Aggregated after 2 years
Push トークンPush token 起動時On app boot 起動時 last_seen_at 更新last_seen_at refreshed on boot 30日アクセスなしで削除Deleted after 30 days of inactivity

7.5 データ更新ポリシー 7.5 Update policy