Adopt shared-SA model, add DEPLOY guide, MIT license
- Install flow now assumes one admin-distributed service account JSON shared across the team. Each user creates their own Google Sheet and shares it with the SA email; per-user GCP project setup is gone. - DEPLOY.md: a step-by-step walkthrough for non-technical users following along with an AI agent (Terminal basics, screenshots-worth of expected output, common-error table). - scripts/append_row.py: sheet_id field accepts either a bare ID or a full Google Sheets URL; normalize_sheet_id() extracts the ID via regex. - scripts/setup.md: rewritten as an admin guide (one-time GCP setup, key rotation) plus a troubleshooting reference. - LICENSE: MIT (previously "private — internal use"). README license sections updated to match. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
@@ -26,6 +27,13 @@ from googleapiclient.discovery import build
|
||||
|
||||
CONFIG_PATH = Path(__file__).resolve().parent.parent / "config.json"
|
||||
|
||||
|
||||
def normalize_sheet_id(value: str) -> str:
|
||||
# Accept either a bare sheet ID or a full Google Sheets URL —
|
||||
# e.g. https://docs.google.com/spreadsheets/d/<ID>/edit#gid=0.
|
||||
m = re.search(r"/d/([a-zA-Z0-9_-]+)", value.strip())
|
||||
return m.group(1) if m else value.strip()
|
||||
|
||||
COLUMNS = [
|
||||
"date", "merchant", "category", "amount", "currency",
|
||||
"amount_hkd", "fx_rate", "fx_date", "payment_method",
|
||||
@@ -63,7 +71,7 @@ def main() -> int:
|
||||
svc.spreadsheets()
|
||||
.values()
|
||||
.append(
|
||||
spreadsheetId=cfg["sheet_id"],
|
||||
spreadsheetId=normalize_sheet_id(cfg["sheet_id"]),
|
||||
range=f"{cfg['worksheet']}!A1",
|
||||
valueInputOption="USER_ENTERED",
|
||||
insertDataOption="INSERT_ROWS",
|
||||
|
||||
Reference in New Issue
Block a user