Sell resources endpoint and postgres function
This commit is contained in:
parent
8aa241afdd
commit
08b227200b
1
.gitignore
vendored
1
.gitignore
vendored
@ -42,3 +42,4 @@ database.db
|
|||||||
.env
|
.env
|
||||||
/sql/create-users.sql
|
/sql/create-users.sql
|
||||||
/.dir-locals.el
|
/.dir-locals.el
|
||||||
|
sql/queries.sql
|
||||||
|
12
README.md
12
README.md
@ -26,13 +26,5 @@ DB_DATABASE=
|
|||||||
|
|
||||||
## API Endpoints
|
## API Endpoints
|
||||||
|
|
||||||
POST `/user/login` check if user exists
|
Refer to ~test-endpoints.restclient~ for an up-to-date list of endpoints. If you want to use this to
|
||||||
GET `/user/USER_ID/stakes` get stake event
|
actually query the endpoints, it's not too hard to setup with Emacs.
|
||||||
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
|
|
||||||
|
@ -54,6 +54,60 @@ begin
|
|||||||
end;
|
end;
|
||||||
$$ language plpgsql;
|
$$ 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)
|
create or replace function clear_user_data(p_user_id uuid)
|
||||||
returns void
|
returns void
|
||||||
as $$
|
as $$
|
||||||
|
@ -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;
|
|
||||||
|
|
@ -75,7 +75,7 @@ export default function Home() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const fetchBankAccount = async () => {
|
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();
|
const bankAccount = await response.json();
|
||||||
setBankAccount(bankAccount);
|
setBankAccount(bankAccount);
|
||||||
};
|
};
|
||||||
@ -171,17 +171,27 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO Joe create sql
|
|
||||||
const sellResource = async (pairs: IConversionPair[]) => {
|
const sellResource = async (pairs: IConversionPair[]) => {
|
||||||
console.log("Selling resource");
|
const response = await fetch(`/api/user/${userId}/account`, {
|
||||||
const response = await fetch(`/api/user/${userId}/bank-account`, {
|
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
pairs: pairs,
|
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) => {
|
const buyStoreItem = async (storeItemId: number) => {
|
||||||
@ -293,10 +303,6 @@ export default function Home() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSetLightBox = () => {
|
|
||||||
setLightBoxIsActive(!lightBoxIsActive);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCloseNotification = () => {
|
const handleCloseNotification = () => {
|
||||||
setNotification(null);
|
setNotification(null);
|
||||||
};
|
};
|
||||||
@ -316,7 +322,7 @@ export default function Home() {
|
|||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return <p>Loading...</p>;
|
return <p>Loading...</p>;
|
||||||
}
|
}
|
||||||
console.log(stakingSources);
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Navbar setUserId={setUserId} />
|
<Navbar setUserId={setUserId} />
|
||||||
|
@ -8,9 +8,9 @@ export default async function handler(
|
|||||||
res: NextApiResponse
|
res: NextApiResponse
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
const db = postgresConnection;
|
||||||
if (req.method === "GET") {
|
if (req.method === "GET") {
|
||||||
const { userId } = req.query;
|
const { userId } = req.query;
|
||||||
const db = postgresConnection;
|
|
||||||
|
|
||||||
if (!checkIfValidUUID(userId)) {
|
if (!checkIfValidUUID(userId)) {
|
||||||
return res.status(400).json({error: "Invalid UUID for user id"});
|
return res.status(400).json({error: "Invalid UUID for user id"});
|
||||||
@ -23,19 +23,21 @@ export default async function handler(
|
|||||||
} else {
|
} else {
|
||||||
return res.status(400).json({error: "Could not find accounts for user"});
|
return res.status(400).json({error: "Could not find accounts for user"});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (req.method === "PUT") {
|
} else if (req.method === "PUT") {
|
||||||
// sell resource
|
|
||||||
// payload userId, key:resourceName/value:amount
|
|
||||||
const { userId } = req.query;
|
const { userId } = req.query;
|
||||||
// an array of IConversionPairs
|
|
||||||
const { pairs } = req.body;
|
const { pairs } = req.body;
|
||||||
// check they have appropriate amount of each resource
|
|
||||||
// increment balance
|
const result = await db.query("select * from sell_resources($1, $2)", [userId, JSON.stringify(pairs)]);
|
||||||
// decrement resources
|
if (result.rowCount > 0) {
|
||||||
|
return res.status(200).json(result.rows);
|
||||||
|
} else {
|
||||||
|
return res.status(400).json({error: "Could not find accounts for user"});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
res.status(500).json(error);
|
res.status(500).json(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,9 +17,25 @@ POST http://localhost:3000/api/user/login
|
|||||||
{ "wallet" : "Wallet12345678" }
|
{ "wallet" : "Wallet12345678" }
|
||||||
|
|
||||||
# Get bank account
|
# Get bank account
|
||||||
GET http://localhost:3000/api/user/:user_id/bank-account
|
GET http://localhost:3000/api/user/:user_id/account
|
||||||
:headers
|
: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
|
# Clear user data
|
||||||
POST http://localhost:3000/api/user/:user_id/clear-data
|
POST http://localhost:3000/api/user/:user_id/clear-data
|
||||||
:headers
|
:headers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user