Compare commits
2 Commits
21d078ed37
...
cc68af5a68
| Author | SHA1 | Date | |
|---|---|---|---|
| cc68af5a68 | |||
| 8b3fd59a69 |
@ -1,3 +1,60 @@
|
|||||||
|
|
||||||
|
import dotenv from "dotenv";
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
export const productResourceUsageQuery = `SELECT DISTINCT
|
||||||
|
line_item_product_code AS productCode,
|
||||||
|
COALESCE(NULLIF(TRIM(product_region_code), ''), 'global') AS regionCode,
|
||||||
|
line_item_usage_account_id AS accountId,
|
||||||
|
line_item_resource_id AS resourceId,
|
||||||
|
line_item_usage_type AS usageType,
|
||||||
|
line_item_usage_amount AS usageAmount,
|
||||||
|
line_item_unblended_rate AS unblendedRate,
|
||||||
|
line_item_unblended_cost AS unblendedCost,
|
||||||
|
line_item_blended_rate AS blendedRate,
|
||||||
|
line_item_blended_cost AS blendedCost,
|
||||||
|
pricing_term AS pricingTerm,
|
||||||
|
pricing_unit AS pricingUnit,
|
||||||
|
pricing_rate_code AS pricingRateCode,
|
||||||
|
pricing_currency AS pricingCurrency,
|
||||||
|
line_item_usage_start_date AS startDate,
|
||||||
|
line_item_usage_end_date AS endDate
|
||||||
|
FROM ${process.env.ATHENA_CU_TABLE}
|
||||||
|
WHERE line_item_usage_account_id = '%accountId%'
|
||||||
|
AND COALESCE(NULLIF(TRIM(product_region_code), ''), 'global') = '%regionCode%'
|
||||||
|
AND LOWER(line_item_product_code) = LOWER('%productCode%')
|
||||||
|
AND line_item_resource_id = '%resourceId%'
|
||||||
|
ORDER BY line_item_usage_start_date ASC;`;
|
||||||
|
|
||||||
|
|
||||||
|
export const allProductUsageQuery = `SELECT DISTINCT
|
||||||
|
line_item_product_code AS productCode,
|
||||||
|
COALESCE(NULLIF(TRIM(product_region_code), ''), 'global') AS regionCode,
|
||||||
|
line_item_usage_account_id AS accountId,
|
||||||
|
line_item_resource_id AS resourceId,
|
||||||
|
line_item_usage_type AS usageType,
|
||||||
|
line_item_usage_amount AS usageAmount,
|
||||||
|
line_item_unblended_cost AS unblendedCost,
|
||||||
|
line_item_blended_cost AS blendedCost,
|
||||||
|
line_item_usage_start_date AS startDate,
|
||||||
|
line_item_usage_end_date AS endDate
|
||||||
|
FROM ${process.env.ATHENA_CU_TABLE}
|
||||||
|
ORDER BY productCode, regionCode, accountId, startDate ASC;`;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// /accounts/cost-usage-summary
|
||||||
|
export const accountCostUsageSummaryQuery = `
|
||||||
|
SELECT
|
||||||
|
line_item_usage_account_id AS accountId,
|
||||||
|
SUM(line_item_usage_amount) AS totalUsageAmount,
|
||||||
|
SUM(line_item_unblended_cost) AS totalUnblendedCost,
|
||||||
|
SUM(line_item_blended_cost) AS totalBlendedCost
|
||||||
|
FROM ${process.env.ATHENA_CU_TABLE}
|
||||||
|
GROUP BY line_item_usage_account_id
|
||||||
|
ORDER BY totalUnblendedCost DESC;
|
||||||
|
`;
|
||||||
|
|
||||||
export const currentMonthSummary = `
|
export const currentMonthSummary = `
|
||||||
SELECT
|
SELECT
|
||||||
SUM(line_item_blended_cost) as totalBlendedCost,
|
SUM(line_item_blended_cost) as totalBlendedCost,
|
||||||
|
|||||||
51
server.js
51
server.js
@ -1,9 +1,11 @@
|
|||||||
import Fastify from "fastify";
|
import Fastify from "fastify";
|
||||||
|
import cors from "@fastify/cors";
|
||||||
import sequelizePlugin from "./plugins/sequelize.js";
|
import sequelizePlugin from "./plugins/sequelize.js";
|
||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
import cors from "@fastify/cors";
|
import cors from "@fastify/cors";
|
||||||
import { executeQueryAsync, retrieveResultsAsync } from "./services/athena.js";
|
import { executeQueryAsync, retrieveResultsAsync } from "./services/athena.js";
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
import * as dashboard from "./queries/dashboard.js";
|
||||||
import * as queries from "./queries/queries.js";
|
import * as queries from "./queries/queries.js";
|
||||||
import * as dashboardQueries from "./queries/dashboard.js";
|
import * as dashboardQueries from "./queries/dashboard.js";
|
||||||
|
|
||||||
@ -13,6 +15,12 @@ await server.register(cors, {
|
|||||||
});
|
});
|
||||||
server.register(sequelizePlugin);
|
server.register(sequelizePlugin);
|
||||||
|
|
||||||
|
await server.register(cors, {
|
||||||
|
origin: "*",
|
||||||
|
});
|
||||||
|
// await server.register(cors, {
|
||||||
|
// origin: ["http://localhost:3000"],
|
||||||
|
// });
|
||||||
server.get("/", async (request, reply) => {
|
server.get("/", async (request, reply) => {
|
||||||
const [results, metadata] = await server.sequelize.query('SELECT 1 + 2 AS result');
|
const [results, metadata] = await server.sequelize.query('SELECT 1 + 2 AS result');
|
||||||
console.log(results);
|
console.log(results);
|
||||||
@ -225,6 +233,47 @@ server.get("/invoices/:invoiceId/accounts/:accountId/products/:productCode/usage
|
|||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.get("/accounts/:accountId/regions/:regionCode/products/:productCode/resources/:resourceId/usage", async (request, reply) => {
|
||||||
|
let regionCode = request.params.regionCode;
|
||||||
|
if (!regionCode || regionCode === 'global') {
|
||||||
|
regionCode = 'global';
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = dashboard.productResourceUsageQuery
|
||||||
|
.replace('%accountId%', request.params.accountId)
|
||||||
|
.replace('%regionCode%', regionCode)
|
||||||
|
.replace('%productCode%', request.params.productCode)
|
||||||
|
.replace('%resourceId%', request.params.resourceId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const queryExecutionId = await executeQueryAsync(query);
|
||||||
|
const results = await retrieveResultsAsync(queryExecutionId);
|
||||||
|
return results ?? [];
|
||||||
|
} catch (err) {
|
||||||
|
request.log.error(err);
|
||||||
|
return reply.status(500).send({
|
||||||
|
error: 'Failed to fetch resource usage',
|
||||||
|
details: err.message,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get("/products/usage", async (request, reply) => {
|
||||||
|
const query = dashboard.allProductUsageQuery;
|
||||||
|
const queryExecutionId = await executeQueryAsync(query);
|
||||||
|
const results = await retrieveResultsAsync(queryExecutionId);
|
||||||
|
return results;
|
||||||
|
});
|
||||||
|
|
||||||
|
server.get("/accounts/cost-usage-summary", async (request, reply) => {
|
||||||
|
const query = dashboard.accountCostUsageSummaryQuery;
|
||||||
|
const queryExecutionId = await executeQueryAsync(query);
|
||||||
|
const results = await retrieveResultsAsync(queryExecutionId);
|
||||||
|
return results;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
server.get("/dashboard/summary", async (request, reply) => {
|
server.get("/dashboard/summary", async (request, reply) => {
|
||||||
const [currentQueryId, previousQueryId] = await Promise.all([
|
const [currentQueryId, previousQueryId] = await Promise.all([
|
||||||
executeQueryAsync(dashboardQueries.currentMonthSummary),
|
executeQueryAsync(dashboardQueries.currentMonthSummary),
|
||||||
@ -334,3 +383,5 @@ try {
|
|||||||
server.log.error(err);
|
server.log.error(err);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user