How do I keep a 'running total' of purchases? Say I have an append-only table that records purchases at a store:
create table purchases(
    customer_id int,
    amount numeric(10, 2) -- (in dollars)
);

There's a lot of other queries that want to know the total dollars spent by a customer, so I have a view like this:
create view total_amount_purchased_view
as 
    select customer_id, 
           sum(amount) as total_amount_purchased
      from purchases
  group by customer_id;

The problem is, the purchases table can be very large (much larger than the number of customers), so queries using the view are slow. I can use a materialized view instead, but I would have to refresh the entire view every single purchase (because postgresql does not support single-row refresh of materialized views, you have to recalculate the entire thing. Not sure about other db's).
So, naturally, this leads me to thinking that I should have a table called total_amount_purchased containing the same rows as the view above. I would keep it up-to-date with an insert trigger on the purchases table, which would update a single row.
-- initialize
create table total_amount_purchased_table
as 
    select customer_id, sum(amount) as total_amount_purchased
      from purchases
  group by customer_id;

-- keep it up to date
create or replace function fn_update_total_purchase() returns trigger as $$
begin
    update total_amount_purchased_table
       set total_amount_purchased = total_amount_purchased_table + new.amount
     where customer_id = new.customer_id;
    -- (OR, insert a new row for a new customer, code not shown)
    return new;
end; $$ language plpgsql;

create trigger tr_update_total_purchase 
after insert on purchases for each row
    execute procedure fn_update_total_purchase();

Question 1: Is there a better solution to this?
Question 2: If this is an ok solution, is there any way to enforce that the total_amount_purchased is correct? (The definition of 'Correct' being that it is equal to sum(amount) of purchases? Can I restricts that the only the trigger tr_update_total_purchase can make changes to total_amount_purchased_table?
If the numbers have to be accurate, the trigger solution is the best one.
To prevent the application from messing with the summary table directly, have that table owned by a different user than the one the application uses to connect. Grant only the SELECT privilege to the application user.