feat(meta-data extraction): add client field support
This commit is contained in:
parent
658307f4be
commit
5e748ad682
@ -29,6 +29,7 @@ const ISSUES_HEADER = [
|
||||
"IssueURL",
|
||||
"EstimatedDays",
|
||||
"Importance",
|
||||
"Client",
|
||||
"TotalTimeMinutes",
|
||||
"TimeSummary",
|
||||
"_IssueKey",
|
||||
@ -160,6 +161,7 @@ async function ensureSheet(sheets, spreadsheetId, sheetName, header) {
|
||||
IssueURL: 260,
|
||||
EstimatedDays: 90,
|
||||
Importance: 90,
|
||||
Client: 200,
|
||||
TotalTimeMinutes: 110,
|
||||
TimeSummary: 260,
|
||||
_IssueKey: 220,
|
||||
@ -203,10 +205,11 @@ async function ensureSheet(sheets, spreadsheetId, sheetName, header) {
|
||||
},
|
||||
});
|
||||
} else if (numberCols.has(key)) {
|
||||
const numPattern = key === 'EstimatedDays' ? '#,##0.##' : '#,##0';
|
||||
requests.push({
|
||||
repeatCell: {
|
||||
range: colRange,
|
||||
cell: { userEnteredFormat: { numberFormat: { type: "NUMBER", pattern: "#,##0" }, horizontalAlignment: "CENTER" } },
|
||||
cell: { userEnteredFormat: { numberFormat: { type: "NUMBER", pattern: numPattern }, horizontalAlignment: "CENTER" } },
|
||||
fields: "userEnteredFormat(numberFormat,horizontalAlignment)",
|
||||
},
|
||||
});
|
||||
@ -238,6 +241,30 @@ async function ensureSheet(sheets, spreadsheetId, sheetName, header) {
|
||||
} catch (e) {
|
||||
logger.warn("sheetsAdapter styling failed", { sheetName, err: e && e.message ? e.message : e });
|
||||
}
|
||||
// Ensure EstimatedDays column displays decimals for existing sheets
|
||||
try {
|
||||
const estimatedIdx = header.indexOf('EstimatedDays');
|
||||
if (estimatedIdx >= 0) {
|
||||
// re-fetch to get the sheetId
|
||||
const meta2 = await requestWithRetry(() => sheets.spreadsheets.get({ spreadsheetId, fields: "sheets.properties" }));
|
||||
const sheetObj = (meta2 && meta2.data && meta2.data.sheets || []).find((s) => s.properties && s.properties.title === sheetName);
|
||||
const sheetId = sheetObj && sheetObj.properties && sheetObj.properties.sheetId;
|
||||
if (sheetId != null) {
|
||||
const colRange = { sheetId, startRowIndex: 1, endRowIndex: 10000, startColumnIndex: estimatedIdx, endColumnIndex: estimatedIdx + 1 };
|
||||
const req = {
|
||||
repeatCell: {
|
||||
range: colRange,
|
||||
cell: { userEnteredFormat: { numberFormat: { type: "NUMBER", pattern: "#,##0.##" }, horizontalAlignment: "CENTER" } },
|
||||
fields: "userEnteredFormat(numberFormat,horizontalAlignment)",
|
||||
},
|
||||
};
|
||||
await requestWithRetry(() => sheets.spreadsheets.batchUpdate({ spreadsheetId, requestBody: { requests: [req] } }));
|
||||
logger.info('sheetsAdapter ensured EstimatedDays decimal formatting', { sheetName });
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
logger.warn('sheetsAdapter failed ensuring EstimatedDays format', { sheetName, err: e && e.message ? e.message : e });
|
||||
}
|
||||
}
|
||||
|
||||
ensuredSheets.add(cacheKey);
|
||||
@ -380,6 +407,7 @@ function mapIssueToRow(issue, action, meta = {}) {
|
||||
(issue.html_url || issue.url) || "",
|
||||
meta.estimatedDays != null ? meta.estimatedDays : "",
|
||||
meta.importance != null ? meta.importance : "",
|
||||
meta.client || "",
|
||||
meta.totalTimeMinutes != null ? meta.totalTimeMinutes : "",
|
||||
timeSummary || "",
|
||||
meta.issueKey || `${(issue.repository && issue.repository.full_name) || ''}#${issue.number}`,
|
||||
|
||||
@ -36,8 +36,8 @@ export async function handleWebhook(req, res, next) {
|
||||
// extract repo full name
|
||||
const repoFullName = (event.repository && (event.repository.full_name || (event.repository.owner && event.repository.owner.login && event.repository.name && `${event.repository.owner.login}/${event.repository.name}`))) || "";
|
||||
|
||||
// parse meta (estimated days d, importance i) from frontmatter, labels, or title
|
||||
const meta = { estimatedDays: null, importance: null, estimateSource: null, estimateRaw: null, eventHash, actor: (event.sender && event.sender.login) || null };
|
||||
// parse meta (estimated days d, importance i, client c) from frontmatter, labels, or title
|
||||
const meta = { estimatedDays: null, importance: null, estimateSource: null, estimateRaw: null, eventHash, actor: (event.sender && event.sender.login) || null, client: null };
|
||||
|
||||
const body = event.issue && event.issue.body ? event.issue.body : "";
|
||||
|
||||
@ -51,7 +51,7 @@ export async function handleWebhook(req, res, next) {
|
||||
for (const line of lines) {
|
||||
const idx = line.indexOf(":");
|
||||
if (idx === -1) continue;
|
||||
const key = line.slice(0, idx).trim();
|
||||
const key = line.slice(0, idx).trim().toLowerCase();
|
||||
const val = line.slice(idx + 1).trim();
|
||||
obj[key] = val;
|
||||
}
|
||||
@ -67,6 +67,8 @@ export async function handleWebhook(req, res, next) {
|
||||
if (md) out.d = md[1];
|
||||
const mi = name.match(/i\s*[:=]\s*(\d+)/i);
|
||||
if (mi) out.i = mi[1];
|
||||
const mc = name.match(/c\s*[:=]\s*(.+)/i);
|
||||
if (mc) out.c = mc[1].trim();
|
||||
}
|
||||
return Object.keys(out).length ? out : null;
|
||||
}
|
||||
@ -78,31 +80,36 @@ export async function handleWebhook(req, res, next) {
|
||||
if (md) out.d = md[1];
|
||||
const mi = title.match(/i\s*=\s*(\d+)/i);
|
||||
if (mi) out.i = mi[1];
|
||||
const mc = title.match(/c\s*[:=]\s*(.+)/i);
|
||||
if (mc) out.c = mc[1].trim();
|
||||
return Object.keys(out).length ? out : null;
|
||||
}
|
||||
|
||||
// precedence: frontmatter > labels > title
|
||||
const fm = parseFrontmatter(body);
|
||||
if (fm && (fm.d || fm.i)) {
|
||||
if (fm && (fm.d || fm.i || fm.c)) {
|
||||
if (fm.d) {
|
||||
const d = String(fm.d).replace(/,/g, '.');
|
||||
meta.estimatedDays = Number(d);
|
||||
meta.estimateRaw = fm.d;
|
||||
}
|
||||
if (fm.i) meta.importance = parseInt(fm.i, 10);
|
||||
if (fm.c) meta.client = fm.c;
|
||||
meta.estimateSource = 'frontmatter';
|
||||
} else {
|
||||
const lb = parseFromLabels(event.issue && event.issue.labels);
|
||||
if (lb && (lb.d || lb.i)) {
|
||||
if (lb && (lb.d || lb.i || lb.c)) {
|
||||
if (lb.d) meta.estimatedDays = Number(String(lb.d).replace(/,/g, '.'));
|
||||
if (lb.i) meta.importance = parseInt(lb.i, 10);
|
||||
if (lb.c) meta.client = lb.c;
|
||||
meta.estimateSource = 'label';
|
||||
meta.estimateRaw = lb.d || lb.i || null;
|
||||
} else {
|
||||
const tt = parseFromTitle(event.issue && event.issue.title);
|
||||
if (tt && (tt.d || tt.i)) {
|
||||
if (tt && (tt.d || tt.i || tt.c)) {
|
||||
if (tt.d) meta.estimatedDays = Number(String(tt.d).replace(/,/g, '.'));
|
||||
if (tt.i) meta.importance = parseInt(tt.i, 10);
|
||||
if (tt.c) meta.client = tt.c;
|
||||
meta.estimateSource = 'title';
|
||||
meta.estimateRaw = tt.d || tt.i || null;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user