Skip to content

Commit 8db7d50

Browse files
buty4649claude
andauthored
system: 自動申請 (lumpapply) 一覧・定義取得サブコマンドを追加 (#31)
管理者向けの system lumpapply API を呼び出す `xpoint system lumpapply` サブコマンド群を追加。 - `xpoint system lumpapply list` — GET /api/v1/system/lumpapply で 自動申請登録の一覧を取得する - `xpoint system lumpapply show <lumpapplyid>` — GET /api/v1/system/ lumpapply/{lumpapplyid} で自動申請の定義情報 (CSV フォーマット、 申請者、作成者、最終更新者など) を取得する 定義情報はレスポンスの階層が深いため、生の JSON を返し --jq で 任意フィルタをかけられるようにした。 refs #25 Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 658d174 commit 8db7d50

5 files changed

Lines changed: 372 additions & 0 deletions

File tree

cmd/system_lumpapply.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
package cmd
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strconv"
7+
"strings"
8+
"text/tabwriter"
9+
10+
"github.com/spf13/cobra"
11+
)
12+
13+
var (
14+
systemLumpapplyListOutput string
15+
systemLumpapplyListJQ string
16+
systemLumpapplyShowJQ string
17+
)
18+
19+
var systemLumpapplyCmd = &cobra.Command{
20+
Use: "lumpapply",
21+
Short: "Manage X-point auto-apply (lumpapply) definitions",
22+
}
23+
24+
var systemLumpapplyListCmd = &cobra.Command{
25+
Use: "list",
26+
Short: "List auto-apply (lumpapply) registrations",
27+
Long: "List auto-apply registrations via GET /api/v1/system/lumpapply. Requires an administrator account.",
28+
RunE: runSystemLumpapplyList,
29+
}
30+
31+
var systemLumpapplyShowCmd = &cobra.Command{
32+
Use: "show <lumpapplyid>",
33+
Short: "Show an auto-apply (lumpapply) definition",
34+
Long: `Fetch definition details via GET /api/v1/system/lumpapply/{lumpapplyid}.
35+
36+
The argument is the numeric lumpapplyid (shown by ` + "`" + `system lumpapply list` + "`" + `).
37+
The response is returned as JSON (shape: csv_format / apply / create / lastaprv / ...).
38+
Requires an administrator account.`,
39+
Args: cobra.ExactArgs(1),
40+
RunE: runSystemLumpapplyShow,
41+
}
42+
43+
func init() {
44+
systemCmd.AddCommand(systemLumpapplyCmd)
45+
systemLumpapplyCmd.AddCommand(systemLumpapplyListCmd)
46+
systemLumpapplyCmd.AddCommand(systemLumpapplyShowCmd)
47+
48+
lf := systemLumpapplyListCmd.Flags()
49+
lf.StringVarP(&systemLumpapplyListOutput, "output", "o", "", "output format: table|json (default: table on TTY, json otherwise)")
50+
lf.StringVar(&systemLumpapplyListJQ, "jq", "", "apply a gojq filter to the JSON response (forces JSON output)")
51+
52+
sf := systemLumpapplyShowCmd.Flags()
53+
sf.StringVar(&systemLumpapplyShowJQ, "jq", "", "apply a gojq filter to the JSON response")
54+
}
55+
56+
func runSystemLumpapplyList(cmd *cobra.Command, _ []string) error {
57+
client, err := newClientFromFlags(cmd.Context())
58+
if err != nil {
59+
return err
60+
}
61+
res, err := client.ListLumpapply(cmd.Context())
62+
if err != nil {
63+
return err
64+
}
65+
66+
return render(res, resolveOutputFormat(systemLumpapplyListOutput), systemLumpapplyListJQ, func() error {
67+
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
68+
defer w.Flush()
69+
fmt.Fprintln(w, "ID\tNAME\tFORM_ID\tFORM_CODE\tFORM_NAME\tROUTE_ID\tROUTE_CODE\tROUTE_NAME")
70+
for _, l := range res.Lumpapply {
71+
fmt.Fprintf(w, "%d\t%s\t%d\t%s\t%s\t%d\t%s\t%s\n",
72+
l.ID, l.Name, l.FormID, l.FormCode, l.FormName, l.RouteID, l.RouteCode, l.RouteName,
73+
)
74+
}
75+
return nil
76+
})
77+
}
78+
79+
func runSystemLumpapplyShow(cmd *cobra.Command, args []string) error {
80+
idArg := strings.TrimSpace(args[0])
81+
lumpapplyID, err := strconv.Atoi(idArg)
82+
if err != nil || lumpapplyID <= 0 {
83+
return fmt.Errorf("lumpapplyid must be a positive integer: %q", args[0])
84+
}
85+
86+
client, err := newClientFromFlags(cmd.Context())
87+
if err != nil {
88+
return err
89+
}
90+
91+
raw, err := client.GetLumpapply(cmd.Context(), lumpapplyID)
92+
if err != nil {
93+
return err
94+
}
95+
if systemLumpapplyShowJQ != "" {
96+
return runJQ(raw, systemLumpapplyShowJQ)
97+
}
98+
return writeJSON(os.Stdout, raw)
99+
}

internal/schema/schema_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func TestAliases_Sorted(t *testing.T) {
4141
"service",
4242
"system.form.list",
4343
"system.form.show",
44+
"system.lumpapply.list",
45+
"system.lumpapply.show",
4446
"system.master.data",
4547
"system.master.import",
4648
"system.master.list",
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"method": "GET",
3+
"path": "/api/v1/system/lumpapply",
4+
"summary": "自動申請登録の一覧取得",
5+
"description": "認証ドメインの管理サイトに登録されている自動申請の一覧を取得する。\n管理者権限が必要。\n",
6+
"parameters": [],
7+
"response": {
8+
"type": "object",
9+
"properties": {
10+
"lumpapply": {
11+
"type": "array",
12+
"description": "自動申請情報 (存在しない場合は空配列)",
13+
"items": {
14+
"type": "object",
15+
"properties": {
16+
"id": {
17+
"type": "integer",
18+
"description": "自動申請ID (system lumpapply show で利用)"
19+
},
20+
"name": {
21+
"type": "string",
22+
"description": "自動申請名称"
23+
},
24+
"form_id": {
25+
"type": "integer",
26+
"description": "フォームID"
27+
},
28+
"form_cd": {
29+
"type": "string",
30+
"description": "フォームコード"
31+
},
32+
"form_name": {
33+
"type": "string",
34+
"description": "フォーム名称"
35+
},
36+
"route_id": {
37+
"type": "integer",
38+
"description": "ルートID"
39+
},
40+
"route_cd": {
41+
"type": "string",
42+
"description": "ルートコード"
43+
},
44+
"route_name": {
45+
"type": "string",
46+
"description": "ルート名称"
47+
}
48+
}
49+
}
50+
}
51+
}
52+
}
53+
}
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
{
2+
"method": "GET",
3+
"path": "/api/v1/system/lumpapply/{lumpapplyid}",
4+
"summary": "自動申請の定義情報取得",
5+
"description": "指定された自動申請登録 ID の詳細設定を取得する。\n管理者権限が必要。\n",
6+
"parameters": [
7+
{
8+
"name": "lumpapplyid",
9+
"in": "path",
10+
"required": true,
11+
"type": "integer",
12+
"description": "自動申請ID (system lumpapply list の id)"
13+
}
14+
],
15+
"response": {
16+
"type": "object",
17+
"properties": {
18+
"lumpapply": {
19+
"type": "object",
20+
"properties": {
21+
"name": {
22+
"type": "string",
23+
"description": "自動申請登録名称"
24+
},
25+
"form": {
26+
"type": "object",
27+
"description": "フォーム情報",
28+
"properties": {
29+
"name": {
30+
"type": "string",
31+
"description": "フォーム名称"
32+
},
33+
"code": {
34+
"type": "string",
35+
"description": "フォームコード"
36+
}
37+
}
38+
},
39+
"route": {
40+
"type": "object",
41+
"description": "承認ルート情報",
42+
"properties": {
43+
"name": {
44+
"type": "string",
45+
"description": "ルート名称"
46+
},
47+
"code": {
48+
"type": "string",
49+
"description": "ルートコード"
50+
}
51+
}
52+
},
53+
"import_file": {
54+
"type": "object",
55+
"description": "取込ファイル情報",
56+
"properties": {
57+
"name": {
58+
"type": "string",
59+
"description": "取込ファイル名称"
60+
},
61+
"success": {
62+
"type": "integer",
63+
"description": "成功時処理 (数値)"
64+
},
65+
"success_str": {
66+
"type": "string",
67+
"description": "成功時処理 (文字列)"
68+
},
69+
"failed": {
70+
"type": "integer",
71+
"description": "失敗時処理 (数値)"
72+
},
73+
"failed_str": {
74+
"type": "string",
75+
"description": "失敗時処理 (文字列)"
76+
}
77+
}
78+
},
79+
"first_row": {
80+
"type": "integer",
81+
"description": "取込ファイル1行目の処理 (数値)"
82+
},
83+
"first_row_str": {
84+
"type": "string",
85+
"description": "取込ファイル1行目の処理 (文字列)"
86+
},
87+
"first_colum": {
88+
"type": "integer",
89+
"description": "申請書類の切り替え判定項目 (数値)"
90+
},
91+
"first_colum_str": {
92+
"type": "string",
93+
"description": "申請書類の切り替え判定項目 (文字列)"
94+
},
95+
"remarks": {
96+
"type": "string",
97+
"description": "備考"
98+
},
99+
"apply": {
100+
"type": "object",
101+
"description": "申請者情報",
102+
"properties": {
103+
"usertype": {
104+
"type": "string",
105+
"description": "申請者種別"
106+
},
107+
"usercode": {
108+
"type": "string",
109+
"description": "申請者コード"
110+
},
111+
"username": {
112+
"type": "string",
113+
"description": "申請者氏名"
114+
}
115+
}
116+
},
117+
"create": {
118+
"type": "object",
119+
"description": "作成者情報",
120+
"properties": {
121+
"username": {
122+
"type": "string",
123+
"description": "作成者氏名"
124+
},
125+
"datetime": {
126+
"type": "string",
127+
"description": "作成日"
128+
}
129+
}
130+
},
131+
"lastaprv": {
132+
"type": "object",
133+
"description": "最終更新者情報",
134+
"properties": {
135+
"username": {
136+
"type": "string",
137+
"description": "最終更新者氏名"
138+
},
139+
"datetime": {
140+
"type": "string",
141+
"description": "更新日"
142+
}
143+
}
144+
},
145+
"csv_format": {
146+
"type": "array",
147+
"description": "CSVフォーマット情報",
148+
"items": {
149+
"type": "object",
150+
"properties": {
151+
"seq": {
152+
"type": "integer",
153+
"description": "シーケンス番号"
154+
},
155+
"field_id": {
156+
"type": "string",
157+
"description": "フィールドID"
158+
},
159+
"field_name": {
160+
"type": "string",
161+
"description": "フィールド名称"
162+
},
163+
"page_no": {
164+
"type": "integer",
165+
"description": "ページ番号"
166+
},
167+
"apply_user": {
168+
"type": "boolean",
169+
"description": "申請ユーザー使用判定"
170+
},
171+
"group_key": {
172+
"type": "boolean",
173+
"description": "グループキー使用判定"
174+
}
175+
}
176+
}
177+
}
178+
}
179+
}
180+
}
181+
}
182+
}

internal/xpoint/client.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,30 @@ func (c *Client) GetSystemFormDetail(ctx context.Context, formID int) (*FormDeta
193193
return &out, nil
194194
}
195195

196+
type Lumpapply struct {
197+
ID int `json:"id"`
198+
Name string `json:"name"`
199+
FormID int `json:"form_id"`
200+
FormCode string `json:"form_cd"`
201+
FormName string `json:"form_name"`
202+
RouteID int `json:"route_id"`
203+
RouteCode string `json:"route_cd"`
204+
RouteName string `json:"route_name"`
205+
}
206+
207+
type LumpapplyListResponse struct {
208+
Lumpapply []Lumpapply `json:"lumpapply"`
209+
}
210+
211+
// ListLumpapply calls GET /api/v1/system/lumpapply (admin).
212+
func (c *Client) ListLumpapply(ctx context.Context) (*LumpapplyListResponse, error) {
213+
var out LumpapplyListResponse
214+
if err := c.do(ctx, http.MethodGet, "/api/v1/system/lumpapply", nil, nil, &out); err != nil {
215+
return nil, err
216+
}
217+
return &out, nil
218+
}
219+
196220
type Master struct {
197221
Type int `json:"type"`
198222
TypeName string `json:"type_name"`
@@ -456,6 +480,18 @@ func (c *Client) GetWebhooklog(ctx context.Context, uuid string) (json.RawMessag
456480
return out, nil
457481
}
458482

483+
// GetLumpapply calls GET /api/v1/system/lumpapply/{lumpapplyid} (admin).
484+
// The response shape is complex (csv_format, apply/create/lastaprv, etc.)
485+
// so it is returned as raw JSON for the caller to interpret.
486+
func (c *Client) GetLumpapply(ctx context.Context, lumpapplyID int) (json.RawMessage, error) {
487+
path := fmt.Sprintf("/api/v1/system/lumpapply/%d", lumpapplyID)
488+
var out json.RawMessage
489+
if err := c.do(ctx, http.MethodGet, path, nil, nil, &out); err != nil {
490+
return nil, err
491+
}
492+
return out, nil
493+
}
494+
459495
type WebhookConfig struct {
460496
ID int `json:"id"`
461497
URL string `json:"url"`

0 commit comments

Comments
 (0)