chuni: implement UserCharge APIs, add table for purchased tickets

This commit is contained in:
5ebef5658c5fcb6f5a62e75318bdc7fad90b21bc 2020-07-30 03:34:56 -05:00 committed by Tau
parent a8539b475e
commit 6c22c4287e
16 changed files with 185 additions and 12 deletions

View File

@ -82,6 +82,21 @@ create table "cm_user_activity" (
)
);
create table "cm_user_charge" (
"id" integer primary key not null,
"profile_id" integer not null
references "cm_user_data"("id")
on delete cascade,
"charge_id" integer not null,
"stock" integer not null,
"purchase_date" text not null,
"valid_date" text not null,
"param1" integer not null,
"param2" integer not null,
"param_date" text not null,
constraint "cm_user_charge_uq" unique ("profile_id", "charge_id")
);
create table "cm_user_course" (
"id" integer primary key not null,
"profile_id" integer not null

View File

@ -0,0 +1,14 @@
create table if not exists "cm_user_charge" (
"id" integer primary key not null,
"profile_id" integer not null
references "cm_user_data"("id")
on delete cascade,
"charge_id" integer not null,
"stock" integer not null,
"purchase_date" text not null,
"valid_date" text not null,
"param1" integer not null,
"param2" integer not null,
"param_date" text not null,
constraint "cm_user_charge_uq" unique ("profile_id", "charge_id")
);

View File

@ -1,3 +1,5 @@
import { readAimeId } from "../proto/base";
import { writeUserCharge } from "../proto/userCharge";
import { Repositories } from "../repo";
import { GetUserChargeRequest } from "../request/getUserCharge";
import { GetUserChargeResponse } from "../response/getUserCharge";
@ -6,9 +8,14 @@ export default async function getUserCharge(
rep: Repositories,
req: GetUserChargeRequest
): Promise<GetUserChargeResponse> {
const aimeId = readAimeId(req.userId);
const profileId = await rep.userData().lookup(aimeId);
const items = await rep.userCharge().load(profileId);
return {
userId: req.userId,
length: "0",
userChargeList: [],
length: items.length.toString(),
userChargeList: items.map(writeUserCharge),
};
}

View File

@ -32,6 +32,7 @@ import upsertClientError from "./upsertClientError";
import upsertClientSetting from "./upsertClientSetting";
import upsertClientTestmode from "./upsertClientTestmode";
import upsertUserAll from "./upsertUserAll";
import upsertUserChargelogApi from "./upsertUserChargelogApi";
import createSqlWrapper from "../sql";
import { DataSource } from "../../sql";
@ -113,6 +114,7 @@ export default function chunithm(db: DataSource) {
wrapper.rpc("/UpsertClientSettingApi", upsertClientSetting);
wrapper.rpc("/UpsertClientTestmodeApi", upsertClientTestmode);
wrapper.rpc("/UpsertUserAllApi", upsertUserAll);
wrapper.rpc("/UpsertUserChargelogApi", upsertUserChargelogApi)
const app = express();

View File

@ -13,6 +13,7 @@ import { readUserActivity } from "../proto/userActivity";
import { readUserDataEx } from "../proto/userDataEx";
import { readUserDuelList } from "../proto/userDuelList";
import { readUserPlaylog } from "../proto/userPlaylog";
import { readUserCharge } from "../proto/userCharge";
import { readUserCourse } from "../proto/userCourse";
// It shouldn't need to be said really, but seeing as this message (A) requires
@ -67,6 +68,10 @@ export default async function upsertUserAll(
await rep.userPlaylog().save(profileId, readUserPlaylog(item));
}
for (const item of payload.userChargeList || []) {
await rep.userCharge().save(profileId, readUserCharge(item));
}
for (const item of payload.userCourseList || []) {
await rep.userCourse().save(profileId, readUserCourse(item));
}

View File

@ -0,0 +1,12 @@
import { Repositories } from "../repo";
import { UpsertUserChargelogApiRequest } from "../request/upsertUserChargelogApi";
import { UpsertUserChargelogApiResponse } from "../response/upsertUserChargelogApi";
export default async function UpsertUserChargelogApi(
rep: Repositories,
req: UpsertUserChargelogApiRequest
): Promise<UpsertUserChargelogApiResponse> {
return {
returnCode: "1",
};
}

View File

@ -0,0 +1,9 @@
export interface UserChargeItem {
chargeId: number;
stock: number;
purchaseDate: Date;
validDate: Date;
param1: number;
param2: number;
paramDate: Date;
}

View File

@ -0,0 +1,20 @@
import { Crush, readDate, writeObject } from "./base";
import { UserChargeItem } from "../model/userCharge";
export type UserChargeJson = Crush<UserChargeItem>;
export function readUserCharge(json: UserChargeJson): UserChargeItem {
return {
chargeId: parseInt(json.chargeId),
stock: parseInt(json.stock),
purchaseDate: readDate(json.purchaseDate),
validDate: readDate(json.validDate),
param1: parseInt(json.param1),
param2: parseInt(json.param2),
paramDate: readDate(json.paramDate),
};
}
export function writeUserCharge(obj: UserChargeItem): UserChargeJson {
return writeObject(obj);
}

View File

@ -1,5 +1,3 @@
import { UserCourseRepository } from "./userCourse";
export { Page } from "./_defs";
import { UserActivityRepository } from "./userActivity";
@ -13,6 +11,8 @@ import { UserItemRepository } from "./userItem";
import { UserMapRepository } from "./userMap";
import { UserMusicRepository } from "./userMusic";
import { UserPlaylogRepository } from "./userPlaylog";
import { UserChargeRepository } from "./userCharge";
import { UserCourseRepository } from "./userCourse";
export interface Repositories {
userActivity(): UserActivityRepository;
@ -37,5 +37,7 @@ export interface Repositories {
userPlaylog(): UserPlaylogRepository;
userCharge(): UserChargeRepository;
userCourse(): UserCourseRepository;
}

View File

@ -0,0 +1,4 @@
import { UserChargeItem } from "../model/userCharge";
import { RepositoryN } from "./_defs";
export type UserChargeRepository = RepositoryN<UserChargeItem>;

View File

@ -8,6 +8,7 @@ import { UserMusicDetailJson } from "../proto/userMusic";
import { UserActivityJson } from "../proto/userActivity";
import { UserRecentRatingJson } from "../proto/userRecentRating";
import { UserPlaylogJson } from "../proto/userPlaylog";
import { UserChargeJson } from "../proto/userCharge";
import { UserCourseJson } from "../proto/userCourse";
import { UserDataExJson } from "../proto/userDataEx";
import { UserDuelListJson } from "../proto/userDuelList";
@ -27,6 +28,7 @@ export interface UpsertUserAllRequest {
userActivityList?: UserActivityJson[];
userRecentRatingList?: UserRecentRatingJson[];
userPlaylogList?: UserPlaylogJson[];
userChargeList?: UserChargeJson[];
userCourseList?: UserCourseJson[];
userDataEx?: UserDataExJson[];
userDuelList?: UserDuelListJson[];

View File

@ -0,0 +1,24 @@
export interface UpsertUserChargelogApiRequest {
userId: string;
userChargelog: {
chargeId: string,
price: string,
purchaseDate: Date,
playCount: string,
playerRating: string,
placeId: string,
regionId: string,
clientId: string
};
userCharge: {
chargeId: string,
stock: string,
purchaseDate: Date,
validDate: Date,
param1: string,
param2: string,
paramDate: Date
};
}

View File

@ -1,3 +1,5 @@
import { UserChargeJson } from "../proto/userCharge";
export interface GetUserChargeResponse {
/** Integer, AiMe ID */
userId: string;
@ -5,6 +7,5 @@ export interface GetUserChargeResponse {
/** Integer, number of results returned */
length: string;
/** TBD */
userChargeList: [];
userChargeList: UserChargeJson[];
}

View File

@ -0,0 +1,3 @@
export interface UpsertUserChargelogApiResponse {
returnCode: string;
}

View File

@ -1,5 +1,7 @@
import { SqlUserActivityRepository } from "./userActivity";
import { SqlUserCharacterRepository } from "./userCharacter";
import { SqlUserChargeRepository } from "./userCharge";
import { SqlUserCourseRepository } from "./userCourse";
import { SqlUserDataRepository } from "./userData";
import { SqlUserDataExRepository } from "./userDataEx";
import { SqlUserDuelListRepository } from "./userDuelList";
@ -12,6 +14,8 @@ import { SqlUserPlaylogRepository } from "./userPlaylog";
import { Repositories } from "../repo";
import { UserActivityRepository } from "../repo/userActivity";
import { UserCharacterRepository } from "../repo/userCharacter";
import { UserChargeRepository } from "../repo/userCharge";
import { UserCourseRepository } from "../repo/userCourse";
import { UserDataRepository } from "../repo/userData";
import { UserDataExRepository } from "../repo/userDataEx";
import { UserDuelListRepository } from "../repo/userDuelList";
@ -22,8 +26,6 @@ import { UserMapRepository } from "../repo/userMap";
import { UserMusicRepository } from "../repo/userMusic";
import { UserPlaylogRepository } from "../repo/userPlaylog";
import { Transaction } from "../../sql";
import { UserCourseRepository } from "../repo/userCourse";
import { SqlUserCourseRepository } from "./userCourse";
export class SqlRepositories implements Repositories {
constructor(private readonly _txn: Transaction) {}
@ -36,6 +38,14 @@ export class SqlRepositories implements Repositories {
return new SqlUserCharacterRepository(this._txn);
}
userCharge(): UserChargeRepository {
return new SqlUserChargeRepository(this._txn);
}
userCourse(): UserCourseRepository {
return new SqlUserCourseRepository(this._txn);
}
userData(): UserDataRepository {
return new SqlUserDataRepository(this._txn);
}
@ -71,8 +81,4 @@ export class SqlRepositories implements Repositories {
userPlaylog(): UserPlaylogRepository {
return new SqlUserPlaylogRepository(this._txn);
}
userCourse(): UserCourseRepository {
return new SqlUserCourseRepository(this._txn);
}
}

View File

@ -0,0 +1,47 @@
import sql from "sql-bricks-postgres";
import { createSqlMapper, T } from "../../sql/util";
import { UserChargeRepository } from "../repo/userCharge";
import { Id } from "../../model";
import { Page } from "../repo";
import { UserDataItem } from "../model/userData";
import { UserChargeItem } from "../model/userCharge";
import { Transaction } from "../../sql";
const { readRow, writeRow, colNames } = createSqlMapper({
chargeId: T.number,
stock: T.number,
purchaseDate: T.Date,
validDate: T.Date,
param1: T.number,
param2: T.number,
paramDate: T.Date,
});
export class SqlUserChargeRepository implements UserChargeRepository {
constructor(private readonly _txn: Transaction) {}
async load(profileId: Id<UserDataItem>): Promise<UserChargeItem[]> {
const stmt = sql
.select("*")
.from("cm_user_charge")
.where("profile_id", profileId);
const rows = await this._txn.fetchRows(stmt);
return rows.map(readRow);
}
save(profileId: Id<UserDataItem>, obj: UserChargeItem): Promise<void> {
const stmt = sql
.insert("cm_user_charge", {
id: this._txn.generateId(),
profile_id: profileId,
...writeRow(obj),
})
.onConflict("profile_id", "charge_id")
.doUpdate(colNames);
return this._txn.modify(stmt);
}
}