Skip to content

Conversation

nandenjin
Copy link
Member

@nandenjin nandenjin commented Sep 18, 2025

出力される収支計算書にコンテンツをシリアライズしたQRコードを付し、PDFや印刷済みのデータからsawaganiへの再インポート・編集が可能なようにします。

収支計算書をsawaganiから出力するにあたり、現在は一度出力した内容を修正するのは困難であるという問題があります(sawagani上で入力する表紙の項目は、元データのスプレッドシートから復元できないため)。この機能により、sawaganiは帳票をすぐにでも提出できる状態を保持したまま、一度出力した内容を何度でも再編集できる自由を得ることになります。

image

@nandenjin nandenjin self-assigned this Sep 18, 2025
@nandenjin nandenjin added the enhancement New feature or request label Sep 18, 2025
@nandenjin nandenjin changed the title feat: QRコード経由のインポートを実装 (WIP) feat: QRコード経由のインポートを実装 Sep 18, 2025
@nandenjin nandenjin marked this pull request as draft September 18, 2025 17:14
@nandenjin nandenjin changed the title (WIP) feat: QRコード経由のインポートを実装 feat: QRコード経由のインポートを実装 Sep 18, 2025
@nandenjin nandenjin requested a review from Copilot September 26, 2025 17:00
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements QR code-based data import functionality for sawagani, allowing users to re-import and re-edit financial statements that have been previously exported as PDFs. The feature addresses the limitation where once a financial statement is exported, it becomes difficult to modify the cover page information that was entered in sawagani.

Key changes include:

  • Implementation of QR code generation and scanning for data serialization
  • Addition of PDF import capability alongside existing CSV import
  • Refactoring of serialization logic to use JSONCrush compression instead of base64 encoding

Reviewed Changes

Copilot reviewed 18 out of 20 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/store/data.ts Adds SerializedData type and refactors serialization methods with version tracking
src/lib/serialization.ts New serialization utility using JSONCrush with base64 fallback
src/lib/importer/pdf.ts Complex PDF QR code scanning implementation with image processing
src/lib/importer/index.ts Unified import interface supporting both CSV and PDF files
src/components/RestoreInfo.vue QR code display component for PDF export pages
src/components/ImporterDialog.vue File import dialog with drag-and-drop support
src/index.ts Updates URL hash handling to use new serialization format
package.json Dependency updates and new QR code related libraries

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

nandenjin and others added 9 commits September 26, 2025 17:03
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
@nandenjin nandenjin marked this pull request as ready for review September 26, 2025 17:14
@nandenjin nandenjin requested a review from Copilot September 26, 2025 17:14
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 4 comments.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +122 to +130
* 画像データを黒い部分に応じて縦横のグリッドで分割する
* @param data
* @param bufferSize 検出に使う縮小画像のサイズ
* @returns グリッド領域の配列
*/
function getContentGrid(
data: ImageData,
bufferSize = 64,
threshold = 200,
Copy link
Preview

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic numbers 64 (buffer size) and 200 (threshold) should be defined as named constants with documentation explaining their purpose and how they were determined.

Suggested change
* 画像データを黒い部分に応じて縦横のグリッドで分割する
* @param data
* @param bufferSize 検出に使う縮小画像のサイズ
* @returns グリッド領域の配列
*/
function getContentGrid(
data: ImageData,
bufferSize = 64,
threshold = 200,
* Default buffer size for image downsampling when detecting grid areas.
* This value was chosen to balance performance and accuracy for typical scanned document images.
* Adjust if input images are much larger or smaller.
*/
const DEFAULT_BUFFER_SIZE = 64;
/**
* Threshold for detecting dark regions in the image.
* Pixels with intensity below this value are considered "black".
* Determined empirically for common document scans; adjust for different lighting or image types.
*/
const DEFAULT_THRESHOLD = 200;
/**
* 画像データを黒い部分に応じて縦横のグリッドで分割する
* @param data
* @param bufferSize 検出に使う縮小画像のサイズ
* @param threshold 黒判定の閾値
* @returns グリッド領域の配列
*/
function getContentGrid(
data: ImageData,
bufferSize = DEFAULT_BUFFER_SIZE,
threshold = DEFAULT_THRESHOLD,

Copilot uses AI. Check for mistakes.

import { computed } from 'vue'
import { serialize } from '../lib/serialization'
const chunkSize = 300
Copy link
Preview

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The magic number 300 for chunk size should be defined as a named constant with documentation explaining why this specific value was chosen for QR code data chunking.

Suggested change
const chunkSize = 300
/**
* The maximum number of characters per QR code chunk.
* Chosen as 300 to ensure that the encoded data fits within a QR code of size 150x150 at error correction level 'L',
* and remains reliably scannable across devices. Adjust if QR code capacity or reliability requirements change.
*/
const QR_CODE_CHUNK_SIZE = 300
const chunkSize = QR_CODE_CHUNK_SIZE

Copilot uses AI. Check for mistakes.

Comment on lines +4 to +10
new Promise((resolve) => {
const reader = new FileReader()
reader.addEventListener('load', (e) => {
const text = e.target?.result as string
const { data } = parseCSV<string[]>(text)
resolve(data)
})
Copy link
Preview

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Promise doesn't handle FileReader errors. Add an error event listener to reject the promise when file reading fails.

Suggested change
new Promise((resolve) => {
const reader = new FileReader()
reader.addEventListener('load', (e) => {
const text = e.target?.result as string
const { data } = parseCSV<string[]>(text)
resolve(data)
})
new Promise((resolve, reject) => {
const reader = new FileReader()
reader.addEventListener('load', (e) => {
const text = e.target?.result as string
const { data } = parseCSV<string[]>(text)
resolve(data)
})
reader.addEventListener('error', (e) => {
reject(e)
})

Copilot uses AI. Check for mistakes.

@nandenjin nandenjin merged commit 8a1a90e into dev Sep 26, 2025
2 checks passed
@nandenjin nandenjin deleted the qr-io branch September 26, 2025 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant