Sell resources endpoint and postgres function

This commit is contained in:
Joseph Ferano 2023-04-14 13:18:05 +07:00
parent 8aa241afdd
commit 08b227200b
7 changed files with 102 additions and 71 deletions

1
.gitignore vendored
View File

@ -42,3 +42,4 @@ database.db
.env
/sql/create-users.sql
/.dir-locals.el
sql/queries.sql

View File

@ -26,13 +26,5 @@ DB_DATABASE=
## API Endpoints
POST `/user/login` check if user exists
GET `/user/USER_ID/stakes` get stake event
POST `/user/USER_ID/stakes/claim` claim stake
POST `/user/USER_ID/stakes/start` start stake
GET `/user/USER_ID/bank-account` get balance
PUT `/user/USER_ID/bank-account` sell resource
GET `/user/USER_ID/inventory-items` get inventory items
POST `/user/USER_ID/inventory-items` buy item
GET `/user/USER_ID/staking-sources` get staking sources
POST `/user/USER_ID/staking-sources` create staking source
Refer to ~test-endpoints.restclient~ for an up-to-date list of endpoints. If you want to use this to
actually query the endpoints, it's not too hard to setup with Emacs.

View File

@ -54,6 +54,60 @@ begin
end;
$$ language plpgsql;
create or replace function sell_resources(
p_user_id uuid,
p_resources jsonb
)
returns table (
"resourceName" text,
"resourceAmount" integer,
"returnAmount" integer,
"saleResult" text
)
as $$
declare
resource jsonb;
resource_name text;
resource_amount integer;
return_amount integer;
resource_sell_factor real;
sale_result text;
begin
for resource in select * from jsonb_array_elements(p_resources)
loop
resource_name := resource ->> 'resourceType';
resource_amount := (resource ->> 'resourceAmount')::integer;
sale_result := null;
begin
update resource_account
set balance = balance - resource_amount
where user_id = p_user_id and resource_id = (
select id from resource where name = resource_name
);
exception
when others then
sale_result := 'Error: Insufficient amount';
end;
if sale_result is null then
select value into resource_sell_factor
from game_constants
where key = resource_name || 'ToMoonbucks';
update bank_account
set balance = balance + resource_amount * resource_sell_factor
where user_id = p_user_id
returning resource_amount * resource_sell_factor into return_amount;
sale_result := 'Success';
end if;
return query select resource_name, resource_amount, return_amount, sale_result;
end loop;
end;
$$ language plpgsql;
create or replace function clear_user_data(p_user_id uuid)
returns void
as $$

View File

@ -1,40 +0,0 @@
select * from users;
select * from resource;
select * from resource_account;
select * from bank_account;
select * from resource_account
join users on resource_account.user_id = users.id
join resource on resource.id = resource_account.resource_id
where users.name = 'Harry';
update bank_account
set balance = 2000
from users
where bank_account.user_id = users.id and name = 'Joe';
select * from staking_source;
select * from resource_well;
select * from inventory_item;
select * from upgrade_event;
delete from upgrade_event;
update inventory_item set tier = 0;
select * from staking_event;
update staking_event set created_at = '2023-03-30 05:05:39.696926+00'
where id = 'e53ef75e-fbb8-453f-a55c-758683bb0bb4';
select * from claim_event;
delete from claim_event;
alter table store_item alter column price type integer using price::integer;

View File

@ -75,7 +75,7 @@ export default function Home() {
};
const fetchBankAccount = async () => {
const response = await fetch(`/api/user/${userId}/bank-account`);
const response = await fetch(`/api/user/${userId}/account`);
const bankAccount = await response.json();
setBankAccount(bankAccount);
};
@ -171,17 +171,27 @@ export default function Home() {
}
};
// TODO Joe create sql
const sellResource = async (pairs: IConversionPair[]) => {
console.log("Selling resource");
const response = await fetch(`/api/user/${userId}/bank-account`, {
const response = await fetch(`/api/user/${userId}/account`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
pairs: pairs,
}),
});
return await response.json();
if (!response.ok) {
const error = await response.text();
setNotification({ message: error, type: "Error" });
}
if (response.status == 200) {
const data = await response.json();
setNotification({
message: `You've received ${data[0].returnAmount} $MoonBucks`,
type: "Success",
});
fetchBankAccount();
}
};
const buyStoreItem = async (storeItemId: number) => {
@ -293,10 +303,6 @@ export default function Home() {
}
};
const handleSetLightBox = () => {
setLightBoxIsActive(!lightBoxIsActive);
};
const handleCloseNotification = () => {
setNotification(null);
};
@ -316,7 +322,7 @@ export default function Home() {
if (isLoading) {
return <p>Loading...</p>;
}
console.log(stakingSources);
return (
<>
<Navbar setUserId={setUserId} />

View File

@ -8,9 +8,9 @@ export default async function handler(
res: NextApiResponse
) {
try {
const db = postgresConnection;
if (req.method === "GET") {
const { userId } = req.query;
const db = postgresConnection;
if (!checkIfValidUUID(userId)) {
return res.status(400).json({error: "Invalid UUID for user id"});
@ -23,19 +23,21 @@ export default async function handler(
} else {
return res.status(400).json({error: "Could not find accounts for user"});
}
} else if (req.method === "PUT") {
const { userId } = req.query;
const { pairs } = req.body;
const result = await db.query("select * from sell_resources($1, $2)", [userId, JSON.stringify(pairs)]);
if (result.rowCount > 0) {
return res.status(200).json(result.rows);
} else {
return res.status(400).json({error: "Could not find accounts for user"});
}
if (req.method === "PUT") {
// sell resource
// payload userId, key:resourceName/value:amount
const { userId } = req.query;
// an array of IConversionPairs
const { pairs } = req.body;
// check they have appropriate amount of each resource
// increment balance
// decrement resources
}
} catch (error) {
res.status(500).json(error);
res.status(500).json(error.message);
}
}

View File

@ -17,9 +17,25 @@ POST http://localhost:3000/api/user/login
{ "wallet" : "Wallet12345678" }
# Get bank account
GET http://localhost:3000/api/user/:user_id/bank-account
GET http://localhost:3000/api/user/:user_id/account
:headers
# Sell a resource
PUT http://localhost:3000/api/user/:user_id/account
:headers
{
"pairs": [
{
"resourceType": "Sollux",
"resourceAmount": 100
},
{
"resourceType": "Novafor",
"resourceAmount": 100
}
]
}
# Clear user data
POST http://localhost:3000/api/user/:user_id/clear-data
:headers